跨域设置

更新时间:
复制为 MD 格式

当网站加载OSS资源时浏览器报"blocked by CORS policy"错误,是因为浏览器的同源策略只允许网页访问相同协议、域名和端口的资源。通过为OSS配置跨域资源共享(CORS)规则,可以安全授权指定网站访问OSS资源。

工作原理

浏览器的同源策略要求网页只能访问相同协议域名端口的资源,三者任一不同即为跨域:

当前页面

请求资源

是否跨域

原因

https://www.example.com

https://www.example.com/api

同源

https://www.example.com

http://www.example.com/api

协议不同

https://www.example.com

https://api.example.com/data

域名不同

https://www.example.com

https://www.example.com:8080/api

端口不同

当网页请求OSS资源时,由于OSS域名与网页域名不同,浏览器会检查OSS是否明确允许该跨域访问。如果OSS未配置相应的CORS规则,浏览器将拒绝访问并报错。

通过在OSS配置CORS规则,可以告诉浏览器哪些跨域请求是被允许的。规则匹配成功后,OSS会在响应中返回Access-Control-Allow-Origin等头部,浏览器收到后才允许网页访问该资源。

配置方式

  1. 前往Bucket列表,单击目标Bucket。

  2. 在左侧菜单栏,选择数据安全 > 跨域设置,单击创建规则,根据需求设置跨域规则参数。

    • 来源:指定哪些网站可以跨域访问,如https://www.example.com

    • 允许 Methods:指定允许的HTTP方法,如GETPUTPOST等。

    • 允许 Headers:指定允许的请求头部,如Authorizationx-oss-*等。

    • 暴露 Headers:指定前端JS可以读取的响应头部,如ETag

    • 缓存时间(秒):指定预检请求结果的缓存时间。

    • 返回 Vary: Origin:多来源或通配符场景下需开启,避免缓存污染。

  3. 单击确定,完成设置。

详细的参数说明请参见CORS参数说明,具体配置值请参考下方场景示例。

场景示例

以下场景展示不同业务需求下的CORS配置方式。

网站静态资源加载

网站https://www.example.com需要加载OSS上的图片、CSSJS文件。

参数

配置值

说明

来源

https://www.example.com

只允许来自该特定网站的跨域请求。

允许 Methods

GET, HEAD

GET下载资源,HEAD用于缓存校验。

允许 Headers

留空

此场景为简单请求,不触发预检,因此该项配置不会被用到。

暴露 Headers

ETag, Content-Length

ETag用于缓存校验,Content-Length用于显示加载进度。

缓存时间(秒)

86400

缓存预检结果24小时,减少预检请求。

返回 Vary: Origin

不勾选

来源单一且确定,无需处理多域名缓存问题。

前端直传文件

用户在网页https://app.example.com上传头像、文档等文件到OSS。

参数

配置值

说明

来源

https://app.example.com

确保只有该授权应用有权限执行上传操作。

允许 Methods

PUT, POST

PUTPOST是执行上传操作必需的HTTP方法。

允许 Headers

*

前端直传的安全性由临时签名(STS或预签名URL)保障,使用*可兼容SDK携带的多种头部。

暴露 Headers

ETag, x-oss-request-id

ETag用于验证上传文件的完整性,x-oss-request-id用于问题排查。

缓存时间(秒)

600

上传操作频率相对较低,缓存10分钟既能减少预检,又能快速响应配置变更。

返回 Vary: Origin

勾选

为未来可能的多域名部署做准备,避免CDN缓存污染。

多环境支持

开发、测试、生产等多个子域名(如dev.example.comapp.example.com)需要访问同一OSS资源。

参数

配置值

说明

来源

https://*.example.com

使用*通配符一次性授权example.com下所有HTTPS协议的子域名。

允许 Methods

GET, PUT, POST

同时允许资源的读取和上传,满足多环境下的测试需求。

允许 Headers

*

多环境开发中,不同环境可能引入不同的自定义头部,使用*可以避免频繁修改CORS规则。

暴露 Headers

ETag, x-oss-request-id

ETag用于缓存校验和上传完整性验证,x-oss-request-id用于问题排查。

缓存时间(秒)

3600

1小时的缓存时间,在多环境切换和调试时较为灵活。

返回 Vary: Origin

勾选

必须开启。告知CDN根据Origin头区分缓存,防止多环境间缓存错乱。

带认证信息的API式调用

前端应用https://api.example.com需要携带Authorization等自定义头部访问受保护的OSS资源。

参数

配置值

说明

来源

https://api.example.com

对于携带认证信息的请求,来源必须是精确的、受信任的域名。

允许 Methods

GET, PUT, DELETE

支持对私有资源的读取、更新和删除全生命周期管理。

允许 Headers

authorization, content-type, x-oss-*

严禁使用*。明确列出所有必要的请求头,遵循最小权限原则。

暴露 Headers

ETag, x-oss-request-id

ETag用于缓存校验和完整性验证,x-oss-request-id用于问题排查。

缓存时间(秒)

600

对于认证类请求,较短的预检缓存时间有助于更快地应用安全策略变更。

返回 Vary: Origin

勾选

告知CDN为不同Origin的请求分别缓存,避免混淆。

CORS请求类型

浏览器根据请求特征,将跨域请求分为简单请求和预检请求两种类型,它们需要的CORS配置项略有不同。

类型

触发条件

需要的CORS配置

简单请求

以下条件同时满足:

  • 请求为GET/HEAD/POST方法

  • POSTContent-Typetext/plainapplication/x-www-form-urlencodedmultipart/form-data

  • 无自定义头部

来源、允许Methods

预检请求

以下条件满足任一:

  • 请求为GET/HEAD/POST外的方法,如PUT/DELETE

  • POSTContent-Type为其他值

  • 有自定义头部(如x-oss-*

来源、允许Methods、允许Headers

简单请求

简单请求可以直接发送,处理流程如下:

  1. 浏览器将Origin头部添加到请求中,包含资源来源,例如Origin: https://www.example.com

  2. OSS将请求的HTTP方法以及Origin头部的值与目标BucketCORS配置进行比较。如果存在匹配项,OSS将在响应中包含Access-Control-Allow-Origin头部。

  3. 浏览器接收响应并检查Access-Control-Allow-Origin值是否与原始请求的域名匹配。如果匹配则请求成功,否则请求失败。

预检请求

预检请求需要先询问服务器是否允许,处理流程如下:

  1. 浏览器发送一个OPTIONS请求,包含主请求的方法(Access-Control-Request-Method)和头部(Access-Control-Request-Headers)信息。

  2. OSS根据CORS配置检查请求的方法和头部是否被允许。如果预检请求中的任何方法或头部值未包含在目标资源允许的方法和头部集合中,请求将失败,并且不会发送主请求。

  3. 预检通过后,执行与简单请求相同的流程。

CORS参数说明

OSS按照配置的规则顺序,从上到下依次检查,并使用第一条成功匹配的规则。一旦匹配成功,后续规则将不再检查。

参数

是否必须

说明

来源

指定哪些网站可以跨域访问OSS资源。

  • 格式为协议://域名[:端口],例如https://www.example.com

  • 支持*通配符,但每个来源中最多只能使用一个。

    • 有效示例:https://*.example.comhttp://localhost:*

    • 无效示例:https://*.example.*https://*

  • 允许多个来源,每行一个。

允许 Methods

指定允许的HTTP方法。

  • 可选值:GETPUTPOSTDELETEHEAD

  • 允许多个方法。

允许 Headers

指定实际请求中允许携带的HTTP头部,作用于预检请求。

  • 支持*通配符,表示允许所有头部。

  • 允许多个Header,每行一个,大小写不敏感。

暴露 Headers

允许前端JavaScript代码访问OSS响应中的哪些头部信息。

  • 不支持*通配符。

  • 允许多个Header,每行一个。

如需在JS中获取ETagx-oss-request-id,必须在此处添加。

缓存时间(秒)

指定浏览器缓存OPTIONS预检请求结果的时间(单位:秒)。

在缓存有效期内,对同一资源的相同跨域请求将不再发送预检请求。

返回 Vary: Origin

决定是否在响应中添加Vary: Origin头。

此头告知CDN等中间缓存需根据请求的Origin头来区分缓存版本,以避免多来源访问时的缓存污染问题。

重要

当来源配置了多个域名或通配符时,必须开启此项。开启后可能导致CDN缓存命中率下降。

应用于生产环境

安全最佳实践

  • 精确配置来源:除非Bucket完全公开,否则不建议将来源设置为*,应精确指定网站域名。

  • 收紧允许Methods:只开放业务必需的HTTP方法,如只读场景仅配置GETHEAD

  • 明确列出允许Headers:遵循最小权限原则,尽量明确列出必要的请求头,避免使用*

性能最佳实践

  • 优化预检缓存:为缓存时间设置合理的值(如86400秒),可减少预检请求数量,降低延迟和请求成本。

  • 评估Vary: Origin的影响:启用此选项可解决缓存污染问题,但可能导致CDN缓存命中率下降和回源流量成本增加。建议仅在多来源或通配符场景下开启。

结合CDN使用

如果Bucket开启了CDN加速并使用CDN域名访问,跨域请求将首先到达CDN节点。此时有两种配置方式:

  • CDN配置CORS:在CDN控制台配置跨域规则,由CDN直接返回CORS头部。详情请参见配置跨域资源共享

  • 透传源站CORS:CDN透传OSS返回的CORS头部,此时需在OSS配置CORS规则。

OSS侧的CORS配置仅在请求直接访问OSS源站域名、或CDN配置为透传源站响应头时生效。

配额与限制

每个Bucket最多可以配置20条跨域规则。

常见问题

No 'Access-Control-Allow-Origin' header is present on the requested resource报错?

通常是由于浏览器缓存了不带CORS头的旧响应,或者CORS规则配置不当导致请求无法匹配任何规则。建议排查步骤:

  1. 清除浏览器缓存后重新测试。

  2. 检查CORS规则的来源、允许Methods是否与实际请求匹配。

  3. 临时创建一条宽松的CORS规则进行排查:来源设置为*,允许Methods全部勾选,允许Headers设置为*,暴露Headers设置为ETagx-oss-request-id,缓存时间设置为0,勾选返回Vary: Origin。

  4. 若问题仍未解决,在服务器执行以下命令查看跨域请求头:

    curl -v -H 'Origin: <来源地址>' '<OSS资源链接>' -o output.txt

    根据返回结果排查:

    • 如果返回结果存在一个跨域头且符合配置,可能是浏览器缓存导致。请按Ctrl+F5清理浏览器缓存,或将缓存时间设置为0。

    • 如果返回结果存在两个跨域头或不符合配置,可能是使用了CDN加速OSS。

      • 登录CDN控制台临时取消CDN加速确认,确认跨域问题不存在。

      • 确认后,在CDN加速域名的缓存配置 > 修改出站响应头中设置自定义响应头。

  5. 若问题还是没有解决,请参见OSS跨域资源共享(CORS)出现的常见错误及解决方案进一步排查。

The 'Access-Control-Allow-Origin' header has a value '...' that is not equal to the supplied origin报错?

服务器返回了Access-Control-Allow-Origin头,但其值与当前请求的Origin不匹配。这通常是由于缓存问题导致的——当配置了多个网站域名访问OSS时,浏览器或CDN可能记住了给其他网站的访问许可。

解决方案:在CORS规则中开启返回 Vary: Origin选项,或清除浏览器缓存后重新访问。

The value of the 'Access-Control-Allow-Origin' header must not be the wildcard '*' when credentials mode is 'include'报错?

前端代码发送了携带凭证的请求(Access-Control-Allow-CredentialsTrue),但来源被配置为通配符*。出于安全考虑,浏览器不允许使用通配符来源。

解决方案

  • 如果需要在请求中保留Credentials信息,将来源从*修改为具体的域名(例如https://example.com),并确保服务器端Access-Control-Allow-Credentials设置为true

  • 如果不需要在请求中保留Credentials信息,在前端代码中将xhr.withCredentials设置为false,并确保服务器端Access-Control-Allow-Credentials设置为false或不返回该头部。

OSS跨域加载慢如何提升加载速度?

跨域请求的加载速度取决于客户端到OSS Bucket的物理链路,而非跨域本身。如果客户端在中国香港而Bucket在中国内地,存在远距离访问的情况。推荐使用OSS传输加速进行访问。