跨域资源共享CORS(Cross-Origin Resource Sharing)简称跨域访问,是HTML5提供的标准跨域解决方案,允许Web应用服务器进行跨域访问控制,使得跨域数据传输得以安全进行。

背景信息

跨域访问是浏览器出于安全考虑而设置的一个限制,即同源策略。当A、B两个网站属于不同域时,来自于A网站页面中的JavaScript代码访问B网站时,浏览器会拒绝该访问。

例如当运行在同一个浏览器上的不同来源,例如www.example.com和www.test.com请求同一跨域资源时,若www.example.com的请求先到达服务器,服务器将请求的资源带上Access-Control-Allow-Origin的Header,并返回给www.example.com的用户。此时www.test.com也发起了请求,浏览器会将缓存的上一次请求响应返回给用户,Header的内容和CORS的要求不匹配,导致www.test.com请求失败。

同源策略限制从一个源加载的文档或脚本与另一个源的资源进行交互的方式,是用于隔离潜在恶意文件的关键安全机制。同协议、同域名(或 IP)、以及同端口视为同一个域。两个页面的协议、域名和端口(若指定了端口)相同,则视为同源。如下表给出了相对http://www.aliyun.com/org/test.html的同源检测示例:

URL 访问是否成功 原因
http://www.aliyun.com/org/other.html 协议、域名、端口相同
http://www.aliyun.com/org/internal/page.html 协议、域名、端口相同
https://www.aliyun.com/page.html 协议不同(HTTPS)
http://www.aliyun.com:22/dir/page.html 端口不同(22)
http://help.aliyun.com/dir/other.html 域名不同

操作方式

操作方式 说明
控制台 Web应用程序,直观易用
Java SDK 丰富、完整的各类语言SDK demo
Python SDK
PHP SDK
Go SDK
C SDK
.NET SDK

CORS规则

OSS支持根据需求灵活配置CORS规则,实现允许或者拒绝相应的跨域请求。CORS规则仅用来决定是否附加CORS相关的Header,是否拦截跨域请求由浏览器决定。详情请参见 PutBucketCORS

如果实际应用中同时存在CORS和非CORS请求,或者Origin头有多种可能值时,建议配置Vary: Origin头以避免本地缓存错乱。

注意 配置Vary: Origin头时,可能会造成浏览器访问次数或者CDN回源次数增加。

CORS示例

当用户的网站为www.example.com,后端使用了OSS。在网页中提供了使用JavaScript来实现上传功能,但是在该网页中,只能向www.example.com发送请求,向其他网站发送的请求都会被浏览器拒绝。这样将导致用户上传的数据必须从www.example.com中转。

如果设置了跨域访问的话,则可以直接上传文件到OSS而无需从www.example.com中转。具体实现如下:

  1. CORS通过HTTP请求中附带Origin的Header来表明来源域。示例中Origin的Header为www.example.com。
  2. 服务器端接收到这个请求之后,会根据一定的规则判断是否允许该来源域的请求。如果允许,服务器在返回的响应中会附带上Access-Control-Allow-Origin这个Header,内容为www.example.com来表示允许此次跨域访问。如果服务器允许所有的跨域请求,将Access-Control-Allow-Origin的Header设置为星号(*)即可。
  3. 浏览器根据是否返回了对应的Header来决定该跨域请求是否成功,如果没有附加对应的Header,浏览器将会拦截该请求。

有关CORS配置详情,请参见设置跨域访问

常见问题

  • CORS配置项常见错误

    有关CORS配置项常见错误及排查方法,请参见OSS跨域资源共享(CORS)错误及排除

  • 使用CDN域名访问OSS遇到跨域问题

    如果您使用CDN域名访问OSS遇到跨域问题,需在CDN控制台配置跨域规则。详情请参见CDN如何配置跨域资源共享(CORS)

  • 发送跨域请求时报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'.错误

    建议您通过设置xhr.withCredentials = false;来解决此问题。