浏览器默认只允许网页访问同域名资源(同源策略),比如https://www.example.com
只能访问相同域名下的内容。OSS属于不同域名,因此浏览器会阻止访问并报跨域错误:通过为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源站域名时生效。详情请参见CDN跨域资源共享配置。
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 -voa '[$URL1]' -H 'Origin:[$URL2]'
说明[$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传输加速地址来访问,这样会对链路有加速优化,详情请参见传输加速。
传输加速功能可以让全球各地的客户使用优化后的网络来传输数据,极大地提升上传和下载速度,让不同地域的用户都能有很好的访问体验。