Как настроить AWS S3, чтобы POST работал как GET

Facebook заявляет в своей документации по настройке холста:

Наши серверы отправят HTTP-запрос POST на этот веб-адрес. Полученный результат будет отображаться во фрейме Canvas на Facebook.

Мое приложение размещено на AWS S3 как статический веб-сайт с использованием следующей конфигурации CORS:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>HEAD</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

У меня уже возникла проблема. GET запросы работают отлично, но POSTing к http://my-bucket-name.s3-website-us-east-1.amazonaws.com отвечает:

<html>
    <head>
        <title>405 Method Not Allowed</title>
    </head>
    <body>
        <h1>405 Method Not Allowed</h1>
        <ul>
            <li>Code: MethodNotAllowed</li>
            <li>Message: The specified method is not allowed against this resource.</li>
            <li>Method: POST</li>
            <li>ResourceType: OBJECT</li>
            <li>RequestId: 94159551A72424C7</li>
            <li>HostId: +Lcz+XaAzL97Y47OZFvaTwqz4Z7r5koaJGHjZJBBMOTUHyThTfKbZG6IxJtYEbtsXWcb/bFxeI8=</li>
        </ul>
        <hr/>
    </body>
</html>

Шаг 1: ^ Думаю, мне нужно, чтобы это работало.

но подождите, это еще не все

Facebook также требует безопасный URL. поэтому для этого я пошел в cloudfront.

Моя конфигурация выглядит так:

Конфигурация Cloudfront

Дополнительная конфигурация Cloudfront

Как и при работе с S3 напрямую, отправка GET запросов к https://app-cloudfront-id.cloudfront.net/ работает как чемпион, POSTing отвечает на это:

<?xml version="1.0" encoding="UTF-8"?>
<Error>
    <Code>MethodNotAllowed</Code>
    <Message>The specified method is not allowed against this resource.</Message>
    <Method>POST</Method>
    <ResourceType>OBJECT</ResourceType>
    <RequestId>657E87A80AFBB3B0</RequestId>
    <HostId>SY2g4smvhr06kAAQYVMsYeQZ+pSKbIIvsh/OaPBiMADGt5UKut0sXSZkFsnFmcRXQ2PFBVgPK4M=</HostId>
</Error>

Просмотр приложения на facebook.com показывает:

приложение на фейсбуке

Я что-то упустил?


person drewwyatt    schedule 04.04.2016    source источник
comment
Это не проблема CORS - Facebook отправляет POST-запрос вашему приложению, отправляя скрытую форму, он не запрашивает ваш URL-адрес через AJAX.   -  person CBroe    schedule 04.04.2016
comment
@CBroe Я почти уверен, что это проблема CORS. AWS отклоняет запросы POST, независимо от того, делаю ли я их через REST-клиент или посещая страницу facebook (см. Добавленный мной снимок экрана, а также извинения за мой плагин XML, который выглядит странно на снимке экрана)   -  person drewwyatt    schedule 04.04.2016
comment
«AWS отклоняет запрос POST» - и поэтому это не проблема CORS. (CORS вступит в игру только в том случае, если ваш браузер будет выполнять междоменные запросы через JS - и в этом случае браузер откажется выполнять запрос, если удаленная конечная точка не будет поддерживать CORS. Однако здесь сервер говорит: «POST? Я не знаю, что с этим делать») stackoverflow.com/a/32036032/1427878   -  person CBroe    schedule 04.04.2016
comment
@CBroe, в этом есть смысл. спасибо, что прояснили это. Вы знаете, может ли S3 отвечать на POST так, как если бы он был GET? (или, возможно, Cloudfront?)   -  person drewwyatt    schedule 04.04.2016
comment
Насколько я понимаю, S3 - это именно статические документы. Там нет ничего, что могло бы «активировать» сообщение. Разве для этого вам нужен веб-сервер? Это похоже на попытку отправить сообщение в общий файловый ресурс   -  person Nick.McDermaid    schedule 12.04.2017


Ответы (3)


Итак - я тоже подумал, что это должно быть легко и хорошо поддерживаться AWS в 2016 году. Судя по всему, что я прочитал, мы ошибаемся.

Невозможно обслужить индексную страницу для приложения facebook из s3 - с облачным интерфейсом или без него.

Возможно, можно будет обслуживать индексную страницу из альтернативного источника (например, из вашего собственного httpd, где-то запущенного) через cloudfront, а все остальное из s3, но я не пробовал копаться в этой кроличьей норе. И если вам все еще нужно запускать собственный HA httpd ... сложность может не окупаться в зависимости от масштаба ваших активов. т.е. http://www.bucketexplorer.com/documentation/cloudfront--how-to-create-distributions-post-distribution-with-multiple-origin-servers.html

вы можете использовать cloudfront перед вашим собственным httpd источника, обслуживающим статический контент, чтобы воспользоваться преимуществами кеширования и распределения по краям - он просто пересылает POST (и PUT и т. д.) в ваш источник и обходит край кеша.

эти ответы старые, примерно 2011 года, но я не могу найти никаких доказательств того, что с этим что-то изменилось.

https://forums.aws.amazon.com/thread.jspa?messageID=228988𷹼

https://forums.aws.amazon.com/thread.jspa?threadID=62525

Надеюсь, мы сможем получить какую-то активность в этой теме, чтобы доказать, что я ошибаюсь, я мог бы использовать это прямо сейчас.

person keen    schedule 05.04.2016
comment
К этому же выводу я пришел. FWIW: Вот неприятный обходной путь, который я использую: webmastermadesimple.com/blog/ - person drewwyatt; 05.04.2016
comment
ха-ха, это не совсем плохой хак - хотя вы бы побеспокоились о влиянии ограничения скорости bitly на запросы, если у вас есть какой-либо масштабный трафик. - person keen; 06.04.2016
comment
Сейчас 2018 год, и у меня был тот же вопрос. При отсутствии какой-либо конкретной документации от AWS я предполагаю, что вы не можете выполнить POST на статический веб-сайт, потому что он предположительно статический. Если вы хотите обработать какой-либо ввод - как подсказывает семантика POST - вам придется запустить сервер для обработки входящих данных, чтобы сервер не был статическим. - person Sai Ramachandran; 28.05.2018

У меня аналогичная ситуация с использованием одностраничного JS-приложения, где все неразрешенные запросы обычно должны обрабатываться на главной странице /index.html.

Основная проблема заключается в том, что S3 не обрабатывает POST как GET. POST - это запрос на изменение. Существует способ настроить S3 для обработки POST, но он предназначен для модификаций S3, а не для запросов только для чтения, таких как GET.

Чтобы обрабатывать запросы POST, я создал поведение AWS CloudFront, которое перенаправляет ошибки обратно в /index.html с кодом ответа HTTP 200. Таким образом, запрос POST перейдет на главную страницу и будет управляться через приложение. Я проделал то же самое с ошибками 403 и 404.

Конфигурация страницы ошибок AWS CloudFront

Отредактируйте раздачу CloudFront, перейдите на Страницы ошибок и создайте 3 различных пользовательских ответа об ошибках, как показано выше.

К вашему сведению, вы можете легко добавить динамическую сторону через CloudFront, избегая всех проблем с CORS. CloudFront может сочетать оба статический и динамический контент посредством поведения.

person Charlie Hileman    schedule 30.04.2020

Попробуйте создать страницу как объект ответа на функцию Lambda и используйте ApiGateway для создания маршрута для обработки обработки страницы.

Оставьте статический контент на S3, CloudFront для поддержки SSL и Lambda для любой обработки динамических страниц.

person user1970604    schedule 12.11.2017