亚马逊AWS官方博客
CloudFront 跨域问题(CORS)的几种解决方式
1. 背景说明
跨域资源共享是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其它 origin(域,协议和端口),使得浏览器允许访问这些 origin 加载的资源。为了是CORS请求能正常工作,浏览器通常会使用预检(Preflight)请求来验证服务端是否支持CORS。预检请求通常使用OPTIONS方法发起,请求中会包含真实请求中会用到的头和方法。常见的CORS使用场景包括XMLHttpRequest发起api请求、加载CSS文件/字体文件等。在使用CloudFront对源站进行加速时,可能会为不同的资源/接口服务分配独立的域名。如果配置不当就比较容易出现跨域资源共享(CORS)错误,表现为浏览器报错无法加载静态资源或请求API接口。本文将根据源站对CORS支持情况及客户端需求,介绍几种CloudFront CORS错误的解决方式。
2. 解决CloudFront跨域资源共享问题的几种方式
2.1 CloudFront配置前置条件
如之前所述,浏览器会通过预检请求来确认站点是否支持CORS,而预检通常使用OPIONS方法,因此首先要确保CloudFront能够支持OPTIONS方法,示例配置如下。
2.1. 使用源请求策略
若CloudFront源站本身支持CORS,则可通过配置源请求策略来使得CloudFront支持CORS。源请求策略应包含如下标头
- Origin,下拉框选择
- Access-Control-Request-Method,自定义方式添加
- Access-Control-Request-Headers,自定义方式添加
配置完成后,更改CloudFront行为,使用新创建的源请求策略。
注意:为简化操作,也可以直接使用托管的源请求策略Managed-CORS-S3Origin
2.2 使用源响应头策略
除源请求策略、缓存策略之外,亚马逊云科技在2021年为CloudFront添加了响应头策略(Response header policy),以便客户方便的修改返回给客户端的响应头。可使用默认的响应头策略或者根据需要自建。
注意:CloudFront Behavior配置响应头策略之后,需要在请求中带上Origin标头CloudFront才会返回CORS相关Header。
2.3 使用CloudFront Function
某些情况下(比如H5游戏),客户端期望站点的返回中一直包含CORS相关的标头,此时使用前文提到的方法将失效。为使CloudFront固定返回CORS相关标头,需要使用CloudFront Function功能。原理是在边缘节点返回结果给客户端之前,通过边缘节点上执行一段代码更改返回结果的标头。CloudFront样例代码如下:
CloudFront 行为配置如下,其中ForceCORSHeaders为CloudFront Function名称。
借助CloudFront Function的边缘计算能力,还可以实现边缘鉴权、AB测试等功能,更多使用案例请参考这里。
3. 总结
本文介绍了3中解决CloudFront CORS错误解决的方法,对比如下
方法 | 使用难度 | 成本 | 特点 |
源请求策略 | 一般 | 无额外成本 | 需要源站支持CORS |
响应头策略 | 简单 | 无额外成本 | 配置简单 |
CloudFront Function | 较难 | 会产生额外成本,提供免费额度 | 需要编写代码,功能灵活 |
如果需要快速让CloudFront支持CORS,比较方便的方式是使用响应头策略;如果需要CloudFront一直返回CORS标头信息或需要支持其他个性化标头/需求,则可以使用CloudFront Function。
4. 参考资料
- https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS
- https://aws.amazon.com/cn/blogs/networking-and-content-delivery/amazon-cloudfront-introduces-response-headers-policies/
- https://aws.amazon.com/premiumsupport/knowledge-center/no-access-control-allow-origin-error/