当网站加载
OSS
资源时,浏览器报"blocked by CORS policy"错误,是因为浏览器的同源策略:只允许网页访问相同协议、域名和端口的资源。比如网站
https://www.example.com
无法直接访问不同域名的
OSS
资源
https://example-bucket.oss-cn-hangzhou.aliyuncs.com/test.jpg
。
通过为
OSS
配置跨域资源共享(CORS)规则,可以安全授权指定网站访问
OSS
资源,让网页直接操作文件。
工作原理
CORS 请求分为两种类型:简单请求和预检请求。简单请求可以直接发送,预检请求必须先获得许可才能发送主请求。
如果满足以下任何一种情况,系统将对请求执行预检:
-
请求使用的是
GET、HEAD、POST以外的方法。 -
请求使用
POST方法且Content-Type不是text/plain、application/x-www-form-urlencoded或multipart/form-data。 -
请求设置了自定义头部,例如
x-oss-*。
当浏览器向 OSS 发出简单请求时,会发生以下过程:
-
浏览器将
Origin头部添加到请求中。Origin头部包含相应资源的来源,例如Origin: https://www.example.com。 -
OSS 将请求的 HTTP 方法以及
Origin头部的值与目标 Bucket 的 CORS 配置进行比较,查找匹配项。如果存在匹配项,OSS 将在响应中包含Access-Control-Allow-Origin头部。Access-Control-Allow-Origin头部包含初始请求的Origin头部的值。 -
浏览器接收响应并检查
Access-Control-Allow-Origin值是否与原始请求的域名匹配。如果匹配,则请求成功。如果不匹配,或者响应中不存在Access-Control-Allow-Origin头部,则请求失败。
预检请求首先执行以下步骤,成功后再执行与简单请求相同的过程:
-
浏览器发送一个
OPTIONS请求,包含主请求的方法(Access-Control-Request-Method)和头部(Access-Control-Request-Headers)信息 -
OSS 根据 CORS 配置检查请求的方法和头部是否被允许。如果预检请求中的任何方法或标头值未包含在目标资源允许的方法和标头集合中,请求将失败,并且不会发送主请求。
网站静态资源加载
网站
https://www.example.com
需要加载存放在
OSS
上的图片、CSS
及
JS
文件。
步骤一:配置 CORS 规则
登录 OSS 管理控制台 ,进入目标 Bucket 的 数据安全 > 跨域设置 ,创建规则如下:
|
参数 |
配置值 |
说明 |
|
来源 |
|
只允许来自该特定网站的请求,保障资源安全。 |
|
允许 Methods |
|
GET 下载资源,HEAD 用于缓存校验。 |
|
允许 Headers |
留空 |
此场景为简单请求,不触发预检,因此该项配置不会被用到,留空即可。 |
|
暴露 Headers |
|
|
|
缓存时间 |
86400 |
缓存预检结果 24 小时,减少未来可能产生的预检请求。 |
|
返回 Vary Origin |
不勾选 |
由于来源是单一且确定的,无需开启此项来处理多域名缓存问题。 |
步骤二:验证配置
访问
https://www.example.com
,确认
OSS
资源(如图片)加载正常,且浏览器控制台无
CORS
错误。
前端直传文件
用户在网页
https://app.example.com
上,将头像、文档等文件直接上传到
OSS。
步骤一:配置 CORS 规则
登录 OSS 管理控制台 ,进入目标 Bucket 的 数据安全 > 跨域设置 ,创建规则如下:
|
参数 |
配置值 |
说明 |
|
来源 |
|
确保只有该授权应用有权限执行上传操作。 |
|
允许 Methods |
|
PUT 或 POST 是执行上传操作必需的 HTTP 方法。 |
|
允许 Headers |
|
前端直传的安全性不依赖固定的
|
|
暴露 Headers |
|
|
|
缓存时间 |
600 |
上传操作频率相对较低,缓存 10 分钟既能减少预检,又能快速响应配置变更。 |
|
返回 Vary Origin |
勾选 |
为未来可能的多域名部署(如测试环境)做准备,避免 CDN 缓存污染。 |
步骤二:验证配置
在
https://app.example.com
页面执行上传操作,确认文件成功上传至
OSS,且浏览器控制台无
CORS
错误。
多环境支持
开发、测试、生产等多个子域名(如
dev.example.com
,
app.example.com
)需要访问同一个
OSS
资源。
步骤一:配置 CORS 规则
登录 OSS 管理控制台 ,进入目标 Bucket 的 数据安全 > 跨域设置 ,创建规则如下:
|
参数 |
配置值 |
说明 |
|
来源 |
|
使用
|
|
允许 Methods |
|
同时允许资源的读取和上传,满足多环境下的测试需求。 |
|
允许 Headers |
|
多环境开发中,不同环境、不同功能可能引入不同的自定义头部。使用
|
|
暴露 Headers |
|
同时支持下载校验和上传结果反馈。 |
|
缓存时间 |
3600 |
1 小时的缓存时间,在多环境切换和调试时较为灵活。 |
|
返回 Vary Origin |
勾选 |
必须开启。告知
CDN
根据
|
步骤二:验证配置
分别在
https://dev.example.com
和
https://app.example.com
上进行访问或上传测试,确认操作均成功。
带认证信息的 API 式调用
前端应用
https://api.example.com
需要携带
Authorization
等自定义头部访问受保护的
OSS
资源。
步骤一:配置 CORS 规则
登录 OSS 管理控制台 ,进入目标 Bucket 的 数据安全 > 跨域设置 ,创建规则如下:
|
参数 |
配置值 |
说明 |
|
来源 |
|
对于携带认证信息的请求,来源必须是精确的、受信任的域名。 |
|
允许 Methods |
|
支持对私有资源的读取、更新和删除全生命周期管理。 |
|
允许 Headers |
|
严禁使用
|
|
暴露 Headers |
|
提供操作成功后的校验标识和失败后的排错 ID |
|
缓存时间 |
600 |
对于认证类请求,较短的预检缓存时间(10 分钟)有助于更快地应用安全策略变更。 |
|
返回 Vary Origin |
勾选 |
告知 CDN 为不同 Origin 的请求分别缓存,避免混淆。 |
步骤二:验证配置
在
https://api.example.com
页面发起带
Authorization
头的请求,确认能成功访问受保护的
OSS
资源。
应用于生产环境
安全最佳实践
遵循最小权限原则。
-
精确配置
来源(AllowedOrigin):除非 Bucket 是完全公开的,否则严禁将AllowedOrigin设置为*。应精确指定提供服务的网站域名,例如https://www.example.com。 -
收紧
允许 Methods(AllowedMethod):只开放业务必需的 HTTP 方法。如果网站只需要读取数据,则只配置GET和HEAD。 -
具体指定
允许 Headers(AllowedHeader):对于携带认证信息(如Authorization头)的请求,严禁使用*,必须明确列出所有必要的请求头。
性能最佳实践
-
优化预检缓存:为
缓存时间 (MaxAgeSeconds)设置一个合理的值(如86400秒,即 24 小时),可以显著减少预检请求的数量,降低延迟和请求成本。 -
评估
Vary: Origin的影响:启用返回 Vary: Origin虽然可以解决缓存污染问题,但会增加 CDN 缓存的复杂性,可能导致缓存命中率下降和回源流量增加,从而产生额外成本和延迟。请在评估后使用。
CDN 加速场景
如果 Bucket 开启了 CDN 加速并使用 CDN 域名访问,跨域请求将首先到达 CDN 节点。此时,必须在 CDN 控制台配置 CORS 规则,而不是在 OSS。OSS 侧的 CORS 配置仅在请求直接访问 OSS 源站域名时生效。详情请参见 配置跨域资源共享 。
CORS 规则参数说明
每个 Bucket 最多可以配置 20 条跨域规则。OSS 按照配置的规则顺序,从上到下依次检查,并使用第一条成功匹配的规则。一旦匹配成功,后续规则将不再检查。
|
参数 |
是否必须 |
说明 |
|
来源 (AllowedOrigin) |
是 |
指定哪些网站(来源域)可以跨域访问 OSS 资源。
|
|
允许 Methods (AllowedMethod) |
是 |
指定允许的 HTTP 方法。
|
|
允许 Headers (AllowedHeader) |
否 |
作用于预检请求,决定了实际请求中允许携带的 HTTP 头部。
|
|
暴露 Headers (ExposeHeader) |
否 |
允许前端 JavaScript 代码可以访问到 OSS 响应中的哪些头部信息。
|
|
缓存时间 (MaxAgeSeconds) |
否 |
指定浏览器缓存
|
|
返回 Vary: Origin |
否 |
决定是否在响应中添加
重要
开启此项可能导致 CDN 缓存命中率下降。 |
常见问题
报错
No 'Access-Control-Allow-Origin' header is present on the requested resource.
通常是由于浏览器缓存了不带 CORS 头的旧响应,或者 CORS 规则配置不当导致请求无法匹配任何规则。
建议先清除浏览器缓存进行测试。如果仍然报错,请参见以下步骤排查 CORS 跨域规则是否设置正确:
-
在左侧导航栏,选择 数据安全 > 跨域设置 。
-
在跨域设置页面,单击 创建规则 。
-
在 创建跨域规则 面板,将 来源 设置为
*, 允许 Methods 全部勾选, 允许 Headers 设置为*, 暴露 Headers 设置为ETag和x-oss-request-id, 缓存时间(秒) 设置为 0 ,选中 返回 Vary: Origin ,然后单击 确定 。 -
若问题仍然未解决,请任意登录一台服务器,执行以下命令,查看跨域请求头。
curl -v -o output_file.txt -H 'Origin:[$URL2]' '[$URL1]'说明-
[$URL1]为需要请求的 OSS 资源链接。
-
[$URL2]为您配置跨域规则的来源地址。
系统显示类似如下。
-
如果出现返回结果存在一个跨域头且符合您配置的跨域头,可能是由于您第一次请求没有触发跨域,返回的数据被本地缓存;而第二次触发跨域的请求没有请求服务器端,而是直接获取本地的缓存,导致跨域校验失败。 请参考以下解决方法:
-
在浏览器页面单击 Ctrl + F5 ,清理浏览器缓存,然后在测试跨域问题是否还存在。
-
您将该 OSS 资源跨域配置的 缓存时间 设置为 0,避免该资源在客户端进行缓存,每次请求都会重新在服务器端获取鉴权信息。
说明您可以在上传文件时设置文件的 cache-control 为 no-cache,已经上传的文件可以使用 ossutil 工具进行更改,如何设置 cache-control 请参见 set-meta(管理文件元数据) 。
-
使用 CDN 加速 OSS,这样 CDN 所有请求都会返回 CORS 头。
-
-
如果返回结果存在两个跨域头或者不符合您在 OSS 配置的跨域头,可能是由于使用了 CDN 加速 OSS:
-
登录 CDN 控制台 ,临时取消 CDN 加速 OSS,确认跨域问题不存在。
-
确认后,单击具体的域名,依次单击 缓存配置 > 节点 HTTP 响应头 。
-
根据您的实际情况,设定自定义 HTTP 响应头。
-
-
-
若跨域问题还是没有解决,请参见 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 选项,这样可以避免不同网站间的缓存混乱;或者清除浏览器缓存后重新访问。
报错
Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
由于前端代码发送了携带凭证的请求,
Access-Control-Allow-Credentials
为
True
,但
Access-Control-Allow-Origin
的值被配置为通配符
*
,出于安全考虑,不允许使用通配符来源,以防止任意域访问资源并获取
Credentials
信息(包括
Cookies、Authorization Headers
等敏感数据)。
-
如果您需要在请求头中保留
Credentials信息,将Access-Control-Allow-Origin的值从通配符*修改为具体的域名(例如:https://example.com)。 -
如果您不需要在请求头中保留
Credentials信息,您可以在前端代码中将xhr.withCredentials设置为false,并确保服务器端的Access-Control-Allow-Credentials设置为false。
OSS 跨域加载慢如何提升加载速度?
跨域请求实际上是请求 Header 中携带 Origin 头请求 OSS Bucket 中的资源,所以加载快慢不取决于跨域,而是客户端到 OSS Bucket 的物理链路。如果客户端在中国香港,Bucket 是中国内地的,那访问是存在远距离访问的情况,推荐您使用 OSS 传输加速地址来访问,这样会对链路有加速优化,详情请参见 传输加速 。
传输加速功能可以让全球各地的客户使用优化后的网络来传输数据,极大地提升上传和下载速度,让不同地域的用户都能有很好的访问体验。