如何将S3用作静态网页,将EC2用作REST API? (AWS)

时间:2013-06-25 12:09:08

标签: rest amazon-web-services amazon-s3 amazon-ec2 load-balancing

使用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,以便它们可以在同一个域上运行,但路径不同? ( somedomain.com上的API / api somedomain.com上的Web应用

谢谢!

1 个答案:

答案 0 :(得分:11)

您不能拥有具有相同主机名的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更改为example.com,并且浏览器会允许来自的{ www.example.comapi.example.com进行通信。
  • 咬紧牙关并使用CORS。这真的不难,而且it's supported在所有远程浏览器中都有用(IE 8和9这样做,但不是以标准方式)。

第一种方法并不好,因为在这种情况下你几乎不会使用S3。

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

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