<!-- AI_TASK_START: AI标题翻译 -->
[解决方案] 通过 Amazon CloudFront 进行 CORS 配置
<!-- AI_TASK_END: AI标题翻译 -->
<!-- AI_TASK_START: AI竞争分析 -->
# 产品功能分析
## 新功能/新产品概述
本文详细介绍了 Amazon CloudFront 在处理 **CORS**(跨域资源共享)方面的功能扩展,主要针对 web 应用的安全性和互操作性。**CloudFront** 作为 AWS 的内容分发网络服务,通过响应头策略、CloudFront 函数和 Lambda@Edge 等机制,简化 **CORS** 配置。该功能的目标是解决浏览器对跨域请求的限制,确保不同域间的资源访问安全。背景在于,**CORS** 是浏览器用于防范 **CSRF**(跨站请求伪造)等攻击的关键机制,适用于现代 web 应用、API 服务和多域架构。目标用户群包括开发者和运营人员,市场定位聚焦于提升全球内容交付的可靠性和性能,尤其在高流量场景下。
## 关键客户价值
- **安全性和兼容性提升**:通过 **CloudFront** 的 **CORS** 配置,客户可以精确控制允许的来源域,减少潜在安全风险,如未授权访问。该机制在简单和预检请求中确保响应头正确设置,与传统服务器端配置相比,减少了手动错误并提升了跨域兼容性。
- 在多 CDN 架构中,此优势体现为一致的政策管理,避免了不一致问题。
- **性能优化和成本效率**:使用响应头策略可直接在边缘处理 **CORS** 请求,降低延迟并减少源服务器负载,例如通过避免预检请求的额外往返。该方法免费,而使用 CloudFront 函数时虽可能增加成本,但原文指出需评估用例以权衡效益。相比传统 IaaS 架构,**CloudFront** 的边缘计算能力显著降低了运维复杂性。
- 例如,在突发流量场景中,动态调整头信息可提高资源利用率,但如果涉及条件检查,可能需额外函数支持。
- **灵活性和可扩展性**:客户可选择多种配置选项(如预设策略或自定义函数),适应不同规模的应用。相比竞品,此功能提供无缝集成 AWS 生态的优势,如与 S3 结合处理缓存问题,但在大规模组网时,缓存不一致性可能导致临时错误。
## 关键技术洞察
- **技术原理和独特性**:**CloudFront** 通过响应头策略(如 **Access-Control-Allow-Origin**)直接在边缘节点处理 **CORS** 请求,支持简单 **CORS**(仅 GET/POST 等方法)和预检 **CORS**(OPTIONS 请求)。其工作原理涉及浏览器发送预检请求,服务器验证后返回允许头,实现了事件驱动的请求响应流程。该技术的创新点在于无代码配置选项,减少了开发负担,并利用边缘计算(如 CloudFront 函数)动态生成头信息,提升毫秒级响应速度。
- 对于性能影响,边缘处理显著提高了可用性和安全性,但如果源服务器出错,头信息可能缺失,导致 **CORS** 错误。
- **优势和限制**:优势包括降低源服务器负载和延迟优化,例如 Lambda@Edge 可自定义逻辑以处理复杂条件,实现更精细的控制。但可能局限性在于,函数使用会产生额外成本,且在缓存策略下,如果首次请求无 **Origin** 头,可能会导致后续请求失败。该实现挑战可以通过添加函数动态补充头信息来解决,体现了 **CloudFront** 对高并发场景的适应性。
- 与传统方法相比,引入边缘函数显著提升了资源利用率,但冷启动问题在高频请求中需注意。
## 其他信息
原文结尾强调,选择 **CORS** 处理方式需基于应用复杂度和成本评估,例如响应头策略适合简单场景,而边缘函数适用于自定义需求。这有助于客户在多因素环境下优化架构决策。
<!-- AI_TASK_END: AI竞争分析 -->
<!-- AI_TASK_START: AI全文翻译 -->
# 通过 Amazon CloudFront 配置 CORS
**原始链接:** [https://aws.amazon.com/blogs/networking-and-content-delivery/cors-configuration-through-amazon-cloudfront/](https://aws.amazon.com/blogs/networking-and-content-delivery/cors-configuration-through-amazon-cloudfront/)
**发布时间:** 2025-05-16
**厂商:** AWS
**类型:** BLOG
---
跨域资源共享 (CORS) 是一种由 web 浏览器实现的的安全特性,它控制哪些网页或 web 应用程序可以向不同域名或 [origin](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin) 发出请求。换句话说,CORS 是一种机制,用于防止托管在一个域名上的网页请求不同域名的资源,除非目标域名明确允许。这有助于防范潜在的安全漏洞,例如 [cross-site request forgery (CSRF)](https://developer.mozilla.org/en-US/docs/Web/Security/Types_of_attacks#cross-site_request_forgery_csrf),并确保敏感数据不会被未授权的网站访问。CORS 通常通过在服务器端添加特定 HTTP 头部到响应中来配置,表明哪些域名被允许访问其资源。此外,它适用于通过 [XMLHttpRequests](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)、[Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)、[Web Fonts](https://developer.mozilla.org/en-US/docs/Learn/CSS/Styling_text/Web_fonts) 和 [WebGL textures](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL) 从不同于服务网页的域名请求的资源。这有助于确保不同网站或 web 应用程序之间安全且受控的数据共享。
## **跨域工作原理和 CORS 请求/响应头的重要性**
最初,浏览器/客户端向应用程序服务器发送 HTTP 请求,接收数据作为 HTTP 响应,并显示它。在浏览器术语中,当前浏览器 URL 称为当前源,而第三方 URL 称为跨域源。
当你进行跨域请求时,请求-响应过程如下:
1. **发起**:浏览器从托管在一个域名 (域名、方案或端口) 的网页向不同源发送 HTTP 请求。
2. **预检请求 (可选)**:如果请求是非简单请求或使用某些方法 (如 PUT、DELETE) 或带有某些头部 (如 Authorization),则浏览器可能先发送一个预检 OPTIONS 请求到服务器,以确定实际请求是否安全。
3. **服务器处理**:服务器评估其 CORS 策略,以决定是否允许来自请求域的源的请求。它通过检查源请求头部来实现。
4. **CORS 响应头部**:如果服务器允许来自该源的请求,则它在响应中包含特定 CORS 头部,例如 [Access-Control-Allow-Origin](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin),以及其他头部,表明哪些源被允许。
5. **浏览器验证**:浏览器检查响应中的 CORS 头部。如果响应头部允许该请求,则浏览器继续发送实际请求。否则,它会阻塞请求,并在开发者控制台中抛出 CORS 相关错误。
6. **响应处理**:浏览器查看访问控制请求头部,并将返回的数据共享给客户端应用程序。

*图 1: CORS 预检请求工作流程*
或者,如果服务器不想允许跨域访问,则浏览器会以错误消息响应。根据请求的性质,跨域请求流程可能不同,如前述图所示。在以下部分,我们讨论简单 CORS 和预检 CORS 请求。
### **简单 CORS 请求**
简单 CORS 请求是最直接的 CORS 请求类型。它们由现代 web 浏览器在满足某些条件时自动生成,允许跨域请求而不需预检请求。
要被视为简单 CORS 请求,必须满足以下条件:
* **HTTP 方法**:仅允许使用如 GET、POST 或 HEAD 等 HTTP 方法。如果请求使用其他方法,则会触发预检请求。
* **Content-Type 头部**:请求中的 Content-Type 头部必须是以下之一:application/x-www-form-urlencoded、multipart/form-data 或 text/plain。如果使用其他内容类型,则会触发预检请求。
* **自定义头部**:请求中可以包含自定义头部,但仅限于 CORS 规范定义的 [simple](https://fetch.spec.whatwg.org/#cors-safelisted-request-header) 头部。这些简单头部包括常见的如 Accept、Accept-Language、Content-Language 和 Range (仅限 [simple range header value](https://fetch.spec.whatwg.org/#simple-range-header-value))。任何非简单头部都会触发预检请求。
简单 CORS 请求较不复杂且执行更快,因为它们不涉及服务器的预检检查。相反,浏览器会检查上述条件是否满足,如果是,则允许请求继续。
`> GET /test.html HTTP/2`
`> Host: d1234test.cloudfront.net`
`> User-Agent: curl/8.1.2`
`> Accept: */*`
`> **Origin: www.example.com** <----- 表示引发请求的源`
在这种情况下,服务器必须返回 [Access-Control-Allow-Origin](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin) 响应头部。
### **预检 CORS 请求**
预检 CORS 请求比简单 CORS 请求更复杂,用于当请求不符合简单 CORS 请求标准时。预检请求是一个 HTTP OPTIONS 请求,在实际请求之前发送到服务器,以确保服务器支持来自请求域的跨域请求。
触发预检请求的关键因素包括:
* **非简单头部**:当请求包含不被视为“简单”头部的自定义头部时,会生成预检请求。
* **凭证**:如果请求包含凭证 (例如 cookie、HTTP 认证),则通常需要预检请求。
预检请求通过 `Access-Control-Request-Method` 请求头部包含 HTTP 方法,以及通过 `Access-Control-Request-Headers` 头部包含实际请求中使用的其他头部。服务器必须以适当的 CORS 头部响应,表明请求的跨域交互是否被允许。如果服务器批准,则浏览器继续发送实际请求。
`> **OPTIONS** /test.html HTTP/2`
`> Host: d1234test.cloudfront.net`
`> User-Agent: curl/8.1.2`
`> Accept: */*`
`**> Origin: www.example.com **<----- 表示引发请求的源`
`**> Access-Control-Request-Method: GET**`
`**> Access-Control-Request-Headers: x-custom**`
`> **GET** /test.html HTTP/2 <----- 实际请求`
`> Host: d1234test.cloudfront.net`
`> User-Agent: curl/8.1.2`
`> Accept: */*`
`**> Origin: www.example.com** <----- 表示引发请求的源`
`> x-custom: custom-value`
在这种情况下,服务器必须响应这些响应头部:[Access-Control-Allow-Origin](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin)、[Access-Control-Allow-Methods](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods) 和 [Access-Control-Allow-Headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers) 用于预检请求。
## **从 Amazon CloudFront 端配置 CORS**
### **第一选项:[响应头部策略](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/understanding-response-headers-policies.html)**
[Amazon CloudFront](https://aws.amazon.com/cloudfront/) 允许你通过响应头部策略来控制/自定义发送回浏览器的响应头部,几乎不带条件,如下图所示。响应头部策略简化了 HTTP 头部响应操作的过程,让你能够在 CloudFront 中通过控制台或 API 定义 CORS、安全和自定义响应头部作为配置设置。通过使用响应头部策略 (RHP),你无需编写代码,而是使用控制台或 API 定义 CORS/安全/自定义头部。RHP 是免费的且易于配置。
*

*
*图 2: 使用 CloudFront 处理 CORS*
如果你的用例是简单 CORS 需求,你可以使用 Simple CORS AWS 托管 RHP。
如果你的用例也包括预检请求 (也称为 OPTIONS 请求),则可以使用 [CORS-With-Preflight](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-response-headers-policies.html#managed-response-headers-policies-cors-preflight) RHP。
这些策略覆盖更广泛的受众,如果你需要特定策略来仅允许特定源、头部或方法,则可以为自定义 CORS 需求创建自己的 RHP。要创建 RHP,你可以参考 [此 CloudFront 开发者指南](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/creating-response-headers-policies.html)。
### **第二选项:[CloudFront 函数/Lambda@Edge](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-at-the-edge.html)**
如果你的需求是直接在 CloudFront 级别处理 OPTIONS 或需要预检工作器,则可以在 viewer-request 事件上配置 CloudFront 函数。以下代码是示例代码,它会针对 OPTIONS 方法请求直接从边缘响应 CORS 头部,而无需转发请求到源服务器。这可以减少延迟,并降低源服务器的负载,从而提升 web 应用程序的整体性能。
**示例代码:**
`function handler(event) {`
` var request = event.request;`
` var response = {`
` statusCode: 200,`
` statusDescription: 'Ok',`
` headers: { "access-control-allow-methods": { "value": "GET" } }`
` };`
` var headers = response.headers;`
` // If origin header is missing, set it equal to the host header.`
` if (request.method == 'OPTIONS'){`
` headers['access-control-allow-origin'] = {value: "https://example.com"};`
` headers['access-control-allow-methods']= {value: "GET"};`
` headers['access-control-allow-headers']= {value: "X-PINGOTHER"};`
` return response;`
` }`
` return request;`
`}`
对于实际请求,你可以使用 CloudFront 响应头部策略来直接在边缘配置和自定义 CORS 头部。
然而,在某些用例中,需要根据特定条件提供响应中的 CORS 头部值。例如,根据 ‘access-control-allow-origin’ 头部值定义 ‘access-control-allow-headers’ 值。这时,需要在 viewer/origin 响应事件上使用边缘函数,因为 RHP 无法执行条件检查。示例代码可以在 [此 CloudFront 开发者指南](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/example-function-add-cors-header-response.html) 中找到。
如果源遇到错误,如服务器端故障或源不可达,则 CORS 头部可能无法正确设置或缺失,这可能导致 CORS 错误。在这些情况下,正确处理 CORS 对于保持 web 应用程序的安全和可靠性至关重要。因此,你可以在 origin-response 事件上使用 [Lambda@Edge](https://aws.amazon.com/lambda/edge/),编写自定义代码并动态调整 CORS 头部,即使源遇到错误。
### **第三选项: 在源端处理 CORS**
尽管 CloudFront 提供强大的 CORS 处理机制,但在源服务器上处理 CORS 的优势也很显著。实现细粒度控制、一致性 CORS 处理跨多个 CDN,以及通过源特定策略增强安全,可以显著影响 web 应用程序的安全性和性能。
当你在 [Amazon S3](https://aws.amazon.com/s3/) 存储桶或自定义源上启用 CORS 时,你必须选择通过 [缓存策略或源请求策略](https://repost.aws/knowledge-center/no-access-control-allow-origin-error) 转发特定头部,以遵守 CORS 设置。你必须转发的 [头部](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/header-caching.html#header-caching-web-cors) 取决于源 (Amazon S3 或自定义源) 以及是否要缓存 OPTIONS 响应。
然而,如果你配置托管 CORS (Amazon S3 或自定义源) 源请求策略来转发这些头部,并且启用了通过缓存策略 (例如,托管 [CachingOptimized](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-cache-policies.html#managed-cache-caching-optimized) 策略) 进行缓存,则可能会遇到不一致的 CORS 问题。在这种情况下,如果 CloudFront 收到第一个不包含 ‘Origin’ 头部的请求,则默认会缓存第一个不带 CORS 响应的响应,并将其用于该对象的所有后续请求,直至过期。如果用户在该对象过期前请求同一对象,即使后续请求包含 ‘Origin’ 头部,他们也不会获得正确的 CORS 响应头部,导致浏览器无法加载资产。
‘Origin’ 头部是在 viewer 请求中添加到 CloudFront 的,CloudFront 会将其转发到源。可选地,你可以配置 [CloudFront 函数来添加 ‘Origin’ HTTP 头部](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/example-function-add-cors-header-request.html),如果请求中没有此头部。这确保 ‘Origin’ 头部在每个请求中被转发到 CloudFront,然后进一步转发到源。
## **结论**
总之,在 Amazon CloudFront 中处理 CORS 对于确保 web 应用程序与托管在不同源服务器上的资源之间平滑且安全的交互至关重要。CloudFront 响应头部策略提供了一种集中的、高效的方式来管理 CORS 配置,让你能够控制允许的源、头部和方法。
此外,CloudFront 函数和 Lambda@Edge 函数提供了必要的灵活性,让你直接在边缘实现自定义 CORS 逻辑,并与现有工作流程无缝集成。无论是修改响应头部、基于特定条件动态生成 CORS 头部,还是实施复杂的 CORS 规则,这些边缘函数都提供了一种可扩展且高效的选项。除了这些优势,使用边缘函数会产生额外成本 [further costs](https://aws.amazon.com/cloudfront/pricing/#Pricing_components),而配置 CloudFront 响应头部策略则无需额外费用。你应该根据特定用例评估成本效益。
然而,对于需要广泛 CORS 处理需求或细粒度控制的场景,在源服务器上直接处理 CORS 是一个可行的选项。这让你能够保留对 CORS 策略的完全控制,这在多 CDN 架构中非常有用,因为你可以为不同 CDN 在单一位置设置 CORS 策略。
对于 CORS 处理,CloudFront 提供了一系列选项,如响应头部策略、边缘函数,以及在源服务器上处理 CORS 的灵活性。然而,选择哪种方法取决于因素如复杂性、可扩展性和应用程序架构的需求。
## 关于作者

### Rishu Gupta
Rishu 是 AWS 的资深云工程师,帮助用户提升其应用程序的性能和安全。他凭借云专业知识,指导客户解决技术挑战,并设计安全、可扩展的解决方案,以满足他们的需求。除了工作,Rishu 是一个美食爱好者,喜欢尝试各种美食并探索新口味。他还重视与家人和朋友共度美好时光。

### Pawan Prabhu
Pawan Prabhu 是 AWS 的云支持工程师,以及 Amazon CloudFront 和 Amazon Simple Email Service 的主题专家。他专注于为各行业的企业用户提供支持。工作之外,他喜欢旅行到新地方并探索其独特文化。
<!-- AI_TASK_END: AI全文翻译 -->