14

借助 AWS 服务,我们让 Web 应用程序从 S3 存储桶运行,并通过负载均衡器(在 EC2 实例上运行的一组 Node.js 应用程序)通过 REST API 访问数据。

目前我们指定的 URL 如下:

  • API负载均衡器:       api。somedomain.com
  • S3 上的静态 Web 应用程序:        somedomain.com

但是这种设置给我们带来了一系列问题,因为请求是这种设置的 CORS。我们可以使用特殊标头解决 CORS,但这不适用于所有浏览器。

我们想要实现的是在同一个域上运行 API,但路径不同:

  • API 负载均衡器:            somedomain.com /api
  • S3 上的静态 Web 应用程序:       somedomain.com

其中一个想法是将 API 负载均衡器附加到 CDN,如果查询来自“/api/*”路径,则将所有请求转发到负载均衡器。但这不起作用,因为我们的 API 不仅使用 HEAD 和 GET 请求,还使用 ​​POST、PUT、DELETE。

另一个想法是使用第二个 EC2 实例而不是 S3 存储桶来托管网站(使用一些 Web 服务器,如 nginx 或 apache)。但是,当一切都已经就绪(S3 静态内容托管)时,这会产生过多的开销。此外,如果使用此方案,我们将无法获得 Amazon CloudFront 性能的所有优势。

那么,您能否推荐如何组合负载均衡器和 S3,以便它们在同一个域上运行,但路径不同?(somedomain.com /api上的 API 和somedomain.com上的 Web App )

谢谢!

4

2 回答 2

12

您不能拥有具有相同主机名的 EC2 实例和 S3 存储桶。考虑当 Web 浏览器向该主机名发出请求时会发生什么。DNS 将其解析为一个 IP 地址(或多个地址),并将请求的数据包传递到该地址。该地址要么终止于 EC2 实例,要么终止于 S3 存储桶,而不是两者。

据我了解您的情况,您在 S3 上托管了静态网页,其中包含向 EC2 实例发出各种 HTTP 请求的 JavaScript 代码。如果 S3 网页与 EC2 实例位于不同的主机上,那么同源策略将阻止浏览器甚至尝试某些请求。

我能看到的唯一解决方案是:

  • 向 EC2 实例发出所有请求,它会在请求网页时获取 S3 内容并将其传送到浏览器。
  • 让您的 JavaScript 使用 iframe 并将document.domain网页中的 更改为共同的父源。例如,如果您的网页位于www.example.com且您的 EC2 实例位于api.example.com,则 JavaScript 将更document.domain改为 justexample.com并且浏览器将允许来自 from 的 iframe 与www.example.com通信api.example.com
  • 咬紧牙关,使用 CORS。这真的不难,并且所有远程最近的浏览器都支持它(IE 8 和 9 都支持,但不是以标准方式)。

第一种方法不好,因为在这种情况下您几乎完全不使用 S3。

第二种情况对你应该没问题。它应该适用于任何浏览器,因为它不是真正的 CORS。因此不需要 CORS 标头。但这很棘手。

第三种,CORS,方法应该没问题。您的 EC2 实例只需返回正确的标头,告诉 S3 存储桶中的网页它们与 EC2 实例通信是安全的。

于 2013-06-27T02:53:47.397 回答
0

只是想在答案中添加一点,如果我们使用 CORS 方法并且预检请求会增加服务器和网络带宽的开销,我们甚至可以考虑在 CORS 响应中添加标头“Access-Control-Max-Age”

访问控制最大年龄

于 2017-08-12T04:03:05.300 回答