使用AWS服务,我们可以从S3存储桶运行Web应用程序,并通过Load Balancer(在EC2实例上运行的Node.js应用程序集)中的REST API访问数据。
目前我们已将URL指定如下:
但是这个设置给我们带来了一系列问题,因为这个设置请求是CORS。我们可以使用特殊标头解决CORS问题,但这并不适用于所有浏览器。
我们想要实现的是在同一个域上运行API,但路径不同:
其中一个想法是将API Load Balancer附加到CDN,并在查询到达“/ api / *”路径时将所有请求转发到Load Balancer。但这不起作用,因为我们的API不仅使用HEAD和GET请求,还使用POST,PUT,DELETE。
另一个想法是使用第二个EC2实例而不是S3存储桶来托管网站(使用一些网络服务器,如nginx或apache)。但是当所有内容都已到位时(S3静态内容托管),这会产生过多的开销。此外,如果使用此方案,我们将无法获得Amazon CloudFront性能的所有好处。
那么,您是否可以推荐如何组合Load Balancer和S3,以便它们可以在同一个域上运行,但路径不同? ( somedomain.com上的API / api 和 somedomain.com上的Web应用)
谢谢!
答案 0 :(得分:11)
您不能拥有具有相同主机名的EC2实例和S3存储桶。考虑当Web浏览器向该主机名发出请求时会发生什么。 DNS将其解析为IP地址(或多个地址),并将请求的数据包传递到该地址。该地址终止于EC2实例或S3存储桶,而不是两者。
根据我了解您的情况,您在S3上托管了静态网页,其中包含向EC2实例发出各种HTTP请求的JavaScript代码。如果S3网页与EC2实例位于不同的主机上,则相同的源策略将阻止浏览器尝试某些请求。
我能看到的唯一解决方案是:
document.domain
更改为公共父源。例如,如果您的网页位于www.example.com
且您的EC2实例位于api.example.com
,则JavaScript会将document.domain
更改为example.com
,并且浏览器会允许来自的{ www.example.com
与api.example.com
进行通信。 第一种方法并不好,因为在这种情况下你几乎不会使用S3。
第二种情况应该对你没问题。它应该适用于任何浏览器,因为它不是真正的CORS。因此不需要CORS头。但这很棘手。
第三种,CORS,方法应该没问题。您的EC2实例只需返回正确的标题,告诉S3存储桶中的网页,它们可以安全地与EC2实例通信。