跨域资源共享(CORS:Cross-Origin Resource Sharing)是一种机制,它使用额外的 HTTP 头来告诉浏览器,让运行在相同域(Origin)上的 Web 应用被准许访问来自不同源服务器上的指定的资源(也即是 同源策略 的 HTTP 解决方案)。当一个资源从与该资源本身所在的服务器不同的域、协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。
CORS 机制是为了在认可用户发起的请求的同时,阻止恶意注入脚本;并在以下情况发起的 HTTP 请求时触发:
https://example.com
调用 http://example.com
example.com
调用 api.com
example.com
调用 api.example.com
example.com
调用 example.com:3001
浏览器将 CORS 请求分成两类:
只要满足以下条件,就属于简单请求:
application/json
为非简单请求)指示资源的 MIME 类型text/plain
multipart/form-data
application/x-www-form-urlencoded
XMLHttpRequest.upload
属性访问。除了简单请求这些限制外的都为非简单请求。
非简单请求需要满足使用以下任意方法的条件:
最常用于判断是否为简单和非简单请求的方法主要是通过 请求方法 和 Content-Type
头部字段的值。
预请求是 OPTIONS 请求,浏览器会自动添加 Access-Control-Allow-Headers
和 Access-Control-Allow-Methods
头部字段。
需要服务端返回的响应头 Access-Control-Allow-Headers
、Access-Control-Allow-Methods
和 Access-Control-Allow-Origin
。
除了 Access-Control-Allow-Origin
是必须的之外,其他两种只有在不符合简单请求需要的时候服务器才需要添加,比如在简单请求的基础上自定义了一个请求头 X-xx-name: chris
,那么服务器只需要在响应头中添加 Access-Control-Allow-Headers
。
每种响应头都可以使用 *
通配符来表示所有。
可以通过设置 Access-Control-Max-Age
来减少预请求的次数,需要包含在预请求的响应头中,指定在该时间内预请求验证有效,不必每次都进行预请求,它的单位是 s
。如 Access-Control-Max-Age: 1728000
,即有效期为 20 天。
预请求完之后就可以发送正常请求了,正常请求的步骤与简单请求一致,也需要添加 Access-Control-Allow-Origin
响应头。
跨域资源共享标准(Cross-Origin Sharing Standard)允许在下列场景中使用跨域 HTTP 请求:
@font-face
使用跨域字体资源)drawImage
将 Images/viedo
画面绘制到 Canvas⚠️ 注意:HTML 中
<link>
、<script>
、<img>
等标签自带连接属性进行 HTTP 请求是能够无视同源策略的。
如果您正在开发使用 Webview(使用 Cordova 或 Ionic)的移动应用程序,Android 将不会给您带来任何麻烦,但 iOS 上的新 WKWebview 将需要 CORS。这意味着您几乎必须始终将 Access-Control-Allow-Origin
标头设置为 *
,但实际上这并不理想。