通过AWS服务,我们可以从S3存储桶运行Web应用程序,并通过Load Balancer(在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 Load Balancer附加到CDN,并在查询到达“/ api / *”路径时将所有请求转发到Load Balancer。但这不起作用,因为我们的API不仅使用HEAD和GET请求,还使用POST,PUT,DELETE。
另一个想法是使用第二个EC2实例而不是S3存储桶来托管网站(使用一些网络服务器,如nginx或apache)。但是当一切就绪时(S3静态内容托管),这会产生太多的开销。此外,如果使用此方案,我们将无法获得Amazon CloudFront性能的所有好处。
那么,您是否可以推荐如何组合Load Balancer和S3,以便它们可以在相同的域上运行,但具有不同的路径? (API on somedomain.com/ API 和Web应用程序 somedomain.com)
谢谢!
您不能拥有具有相同主机名的EC2实例和S3存储桶。考虑当Web浏览器向该主机名发出请求时会发生什么。 DNS将其解析为IP地址(或多个地址),并将请求的数据包传递到该地址。地址要么终止于EC2实例,要么终止于S3存储桶,而不是两者。
据我所知,您在S3上托管的静态网页包含JavaScript代码,可以向EC2实例发出各种HTTP请求。如果S3网页与EC2实例位于不同的主机上,则相同的源策略将阻止浏览器尝试某些请求。
我能看到的唯一解决方案是:
- 向EC2实例发出所有请求,同时获取S3内容并在需要网页时将其提供给浏览器。
- 让您的JavaScript使用iframe并更改
document.domain
在网页中的共同父源。例如,如果您的网页位于 www.example.com
你的EC2实例是在 api.example.com
,JavaScript会改变 document.domain
到了 example.com
并且浏览器将允许来自的iframe www.example.com
与...沟通 api.example.com
。
- 咬紧牙关并使用CORS。这真的不难,而且 它得到了支持 在所有远程浏览器中(IE 8和9都可以,但不是以标准方式)。
第一种方法并不好,因为在这种情况下你几乎不会使用S3。
第二种情况应该对你没问题。它应该适用于任何浏览器,因为它不是真正的CORS。因此不需要CORS头。但这很棘手。
第三种,CORS,方法应该没问题。您的EC2实例只需返回正确的标题,告诉S3存储桶中的网页,它们可以安全地与EC2实例通信。
您不能拥有具有相同主机名的EC2实例和S3存储桶。考虑当Web浏览器向该主机名发出请求时会发生什么。 DNS将其解析为IP地址(或多个地址),并将请求的数据包传递到该地址。地址要么终止于EC2实例,要么终止于S3存储桶,而不是两者。
据我所知,您在S3上托管的静态网页包含JavaScript代码,可以向EC2实例发出各种HTTP请求。如果S3网页与EC2实例位于不同的主机上,则相同的源策略将阻止浏览器尝试某些请求。
我能看到的唯一解决方案是:
- 向EC2实例发出所有请求,同时获取S3内容并在需要网页时将其提供给浏览器。
- 让您的JavaScript使用iframe并更改
document.domain
在网页中的共同父源。例如,如果您的网页位于 www.example.com
你的EC2实例是在 api.example.com
,JavaScript会改变 document.domain
到了 example.com
并且浏览器将允许来自的iframe www.example.com
与...沟通 api.example.com
。
- 咬紧牙关并使用CORS。这真的不难,而且 它得到了支持 在所有远程浏览器中(IE 8和9都可以,但不是以标准方式)。
第一种方法并不好,因为在这种情况下你几乎不会使用S3。
第二种情况应该对你没问题。它应该适用于任何浏览器,因为它不是真正的CORS。因此不需要CORS头。但这很棘手。
第三种,CORS,方法应该没问题。您的EC2实例只需返回正确的标题,告诉S3存储桶中的网页,它们可以安全地与EC2实例通信。
只是想补充一点,如果我们采用CORS方法和预检请求增加了服务器和网络带宽的开销,我们甚至可以考虑在CORS响应中添加标题“Access-Control-Max-Age”
访问控制 - 最大 - 年龄