Как использовать 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