1、跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器,让Web应用被准许访问来自不同源服务器上的指定的资源
2、例如,XMLHttpRequest和Fetch API遵循同源策略。 这意味着使用这些API的Web应用程序只能从加载应用程序的同一个域请求HTTP资源,
除非响应报文包含了正确CORS响应头
3、什么情况下需要 CORS ?
由 XMLHttpRequest 或 Fetch 发起的跨域 HTTP 请求。
Web 字体 (CSS 中通过 @font-face 使用跨域字体资源), 因此,网站就可以发布 TrueType 字体资源,并只允许已授权网站进行跨站调用
WebGL 贴图
使用 drawImage 将 Images/video 画面绘制到 canvas
4、跨域资源共享标准对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),
浏览器必须首先使用 OPTIONS 方法发起一个预检请求,从而获知服务端是否允许该跨域请求。服务器确认允许之后,
才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,
是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)
简单请求
某些请求不会触发 CORS 预检请求,称这样的请求为 简单请求
若请求满足所有下述条件,则该请求可视为 简单请求:
使用下列方法之一:
GET
HEAD
POST
Fetch 规范定义了对 CORS 安全的首部字段集合,不得人为设置该集合之外的其他首部字段。该集合为:
Accept
Accept-Language
Content-Language
Content-Type (需要注意额外的限制)
DPR
Downlink
Save-Data
Viewport-Width
Width
Content-Type 的值仅限于下列三者之一:
text/plain
multipart/form-data
application/x-www-form-urlencoded
预检请求
要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,预检请求 的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。
当请求满足下述任一条件时,即应首先发送预检请求:
使用了下面任一 HTTP 方法:
PUT
DELETE
CONNECT
OPTIONS
TRACE
PATCH
人为设置了对 CORS 安全的首部字段集合之外的其他首部字段。该集合为:
Accept
Accept-Language
Content-Language
Content-Type (需要注意额外的限制)
DPR
Downlink
Save-Data
Viewport-Width
Width
Content-Type 的值不属于下列之一:
application/x-www-form-urlencoded
multipart/form-data
text/plain
HTTP 响应首部字段
Access-Control-Allow-Origin
Access-Control-Allow-Origin: '*' 允许所有网站请求
Access-Control-Allow-Origin: 'www.baidu.com' 允许百度网站请求
Access-Control-Expose-Headers
在跨域访问时,XMLHttpRequest对象的getResponseHeader()方法只能拿到一些最基本的响应头,
Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,
如果要访问其他头,则需要服务器设置本响应头
Access-Control-Max-Age
Access-Control-Max-Age: '1000' 1000秒内再发送请求不用在发送预请求
Access-Control-Allow-Credentials
指定了当浏览器的credentials设置为true时是否允许浏览器读取response的内容
Access-Control-Allow-Methods
用于预检请求的响应,其指明了实际请求所允许使用的 HTTP 方法
Access-Control-Allow-Headers
用于预检请求的响应,其指明了实际请求中允许携带的首部字段
HTTP 请求首部字段
无须手动设置,当开发者使用 XMLHttpRequest 对象发起跨域请求时,它们已经被设置就绪
Origin
表明预检请求或实际请求的源站
Access-Control-Request-Method
用于预检请求,将实际请求所使用的 HTTP 方法告诉服务器
Access-Control-Request-Headers
用于预检请求,将实际请求所携带的首部字段告诉服务器
附带身份凭证的请求
浏览器不会发送身份凭证信息。如果要发送凭证信息,需要设置 XMLHttpRequest
的某个特殊标志位
XMLHttpRequest
的 withCredentials 标志设置为 true,
从而向服务器发送 Cookies。
因为这是一个简单 GET 请求,所以浏览器不会对其发起 预检请求。但是,如果服务器端的响应中未携带 Access-Control-Allow-Credentials: true,
浏览器将不会把响应内容返回给请求的发送者。