Как использовать S3 как статическую веб-страницу и EC2 как REST API для этого вместе? (АМС)

С AWS-сервисами у нас есть веб-приложение, работающее из ведра S3, и доступ к данным через REST API из Load Balancer (который установлен в приложениях Node.js, запущенных на экземпляре EC2).

В настоящее время мы указали URL следующим образом:

  • Балансировщик API:     апи. somedomain.com
  • Статическое веб-приложение на S3:       somedomain.com

Но наличие этой установки вызвало множество проблем, так как запросы CORS с этой настройкой. Мы могли бы обойти CORS со специальными заголовками, но это не работает со всеми браузерами.

То, что мы хотим достичь, - это запустить API в том же домене, но с другим путем:

  • Балансер загрузки API:             somedomain.com /апи
  • Статическое веб-приложение на S3:     somedomain.com

Одна из идей заключалась в том, чтобы подключить балансировщик нагрузки API к CDN и перенаправить весь запрос на Load Balancer, если запрос идет по пути "/api/*". Но это не работает, поскольку наш API использует не только запросы HEAD и GET, но также POST, PUT, DELETE.

Другая идея - использовать второй экземпляр EC2 вместо ведра S3 для размещения веб-сайта (с использованием какого-либо веб-сервера, такого как nginx или apache). Но это слишком много накладных расходов, когда все уже на месте (S3 статический контент-хостинг). Также, если вы используете этот сценарий, мы не получили бы все преимущества производительности Amazon CloudFront.

Итак, можете ли вы рекомендовать объединить Load Balancer и S3, чтобы они работали в одном домене, но с разными путями? (API на somedomain.com /api и веб-приложение на somedomain.com)

Спасибо!

Ответ 1

У вас не может быть экземпляр EC2 и ведро S3 с тем же именем хоста. Рассмотрим, что происходит, когда веб-браузер делает запрос на это имя хоста. DNS решает его на IP-адрес (или адреса), и пакеты запроса доставляются на этот адрес. Адрес либо завершается в экземпляре EC2, либо в ведро S3, а не в обоих.

Как я понимаю вашу ситуацию, у вас есть статические веб-страницы, размещенные на S3, которые включают код JavaScript, который обрабатывает различные HTTP-запросы к экземпляру EC2. Если веб-страницы S3 находятся на другом хосте, чем экземпляр EC2, то одна и та же политика происхождения не позволит браузеру даже пытаться выполнить некоторые из запросов.

Единственные решения, которые я вижу, следующие:

  • Выполнять все запросы к экземпляру EC2, при этом он извлекает содержимое S3 и доставляет его в браузер всякий раз, когда запрашивается веб-страница.
  • Попросите JavaScript использовать iframe и измените document.domain на веб-страницах на общее родительское происхождение. Например, если ваши веб-страницы находятся в www.example.com, а ваш экземпляр EC2 находится в api.example.com, JavaScript изменит document.domain на example.com, и браузер разрешит iframes из www.example.com для связи с api.example.com > .
  • Укусите пулю и используйте CORS. Это действительно не сложно, и он поддерживался во всех удаленных последних браузерах (IE 8 и 9 делают это, но не стандартным образом).

Первый метод не подходит, потому что в этом случае вы почти не сможете вообще использовать S3.

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

В-третьих, подход CORS должен быть прекрасным. Ваш экземпляр EC2 просто должен вернуть правильные заголовки, сообщающие веб-страницы из ведра S3, чтобы они могли разговаривать с экземпляром EC2.

Ответ 2

Просто хотел добавить дополнительный бит к ответу, который, если мы пойдем с подходами CORS и запросами предполетных приложений, добавит накладные расходы на сервер и пропускную способность сети, мы можем даже рассмотреть возможность добавления заголовка "Access-Control-Max-Age" в ответ CORS

Access-Control-Max-Age