@Dale-Lin
2023-03-08T21:49:27.000000Z
字数 2492
阅读 533
web开发技术
HTTP
CORS(cross-origin resource sharing)跨域资源共享是一种机制,它使用额外的 HTTP 头来告诉浏览器让运行在一个 origin(domain)上的 web 应用被准许访问来自不同源服务器上的指定的资源。
浏览器只是拦截了服务器响应的资源,请求依然被服务器接收并处理。
CORS 允许下列场景使用跨域 HTTP 请求:
常用的前端资源——图片,样式表,脚本默认允许跨域。
支持跨域请求的浏览器会自带
Origin
头部。
Access-Control-Allow-Origin
发起一个跨域请求时,服务器端的响应报文头部携带,表明该资源可访问的域名。例如:
GET /resources/public-data/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Origin: http://foo.example/examples/access-control/simpleXSInvocation.html
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2.0.61
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml
*
表示可被任意外域访问。
可以使用 CORS 的请求方法。
可以使用 CORS 的请求头部。
允许浏览器缓存预检请求的响应(单位:秒),在缓存时间内不需要再发起预检请求。
CORS 属于“需预检的请求”,要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。
检查内容:
当请求满足下述任一条件时,即应首先发送预检请求:
一个需要预检的请求如下:
var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/post-here/';
var body = '<?xml version="1.0"?><person><name>Arun</name></person>';
function callOtherDomain(){
if(invocation)
{
invocation.open('POST', url, true);
invocation.setRequestHeader('X-PINGOTHER', 'pingpong');
invocation.setRequestHeader('Content-Type', 'application/xml');
invocation.onreadystatechange = handler;
invocation.send(body);
}
}
CORS 默认不会携带 cookie,如果需要携带 cookie,需要对 xhr 或 fetch 设置标志位或属性:
XMLHttpRequest.withCredentials = true
Fetch.request.credentials = include
:默认是 same-origin
,即同源才携带 cookie。跨域需要设置成 include
。omit
则永远不接收或发送 cookie。且服务器响应的 Access-Control-Allow-Origin
头部的值不能是 * ,并且响应头部应有 Access-Control-Allow-Crenditials: true
。
HTML5 中,例如 <img>
和 <video>
均有一个 crossorigin
属性,允许配置元素获取数据的跨域请求:
关键字 | 描述 |
---|---|
anonymous (默认) |
不会通过 cookies,客户端 SSL 证书或 HTTP 认证交换用户凭证 |
use-credentials |
请求将提供用户凭证(cookie) |