跨域资源共享(CORS)
同源策略(W3C规定的)
同源策略(Same origin policy)是一种约定,它是==浏览器==最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。所谓同源: 协议、域名、端口相同
出于安全原因,浏览器限制从脚本内发起的跨源HTTP请求
XMLHttpRequest和Fetch API遵循同源策略
解决跨域的方式
- jsonp
用的很少
- 反向代理
做介于服务端和客户端之间的中间层, ==中间层必须和客户端是一个源==,向服务端转发请求,并接受响应再返回给客户端
- CORS
跨域资源共享 今天主讲
何为跨域资源共享(CORS)
跨域资源共享是一种机制,它使用额外的HTTP头来告诉浏览器,让运行在一个域下的web应用运行访问不同域下服务器的资源。
什么情况下使用CORS
- 前文提到的由 XMLHttpRequest 或 Fetch 发起的跨域 HTTP 请求。
- Web 字体 (CSS 中通过 @font-face 使用跨域字体资源), 因此,网站就可以发布 TrueType 字体资源,并只允许已授权网站进行跨站调用。
- WebGL 贴图
- 使用
drawImage
将 Images/video 画面绘制到 canvas
功能概述
通过设置HTTP首部字段,可以允许服务声明哪些域名可以通过浏览器访问哪些资源。针对可能对服务器数据产生副作用的HTTP
请求(特别是除了GET
以外的HTTP请求或者某些搭配MIME类型的POST
请求),浏览器必须使用OPTIONS
发起一个==预检请求==,从而知道服务器端是否允许跨域。服务器端确认之后,才能发起实际的HTTP请求。在预检请求的返回中,服务器端也可以通知客户端,==是否需要携带身份凭证==(包括 Cookies 和 HTTP 认证相关数据)。
简单请求
不会触发 CORS 预检请求
本文称这样的请求为“简单请求”,请注意,该术语并不属于 Fetch (其中定义了 CORS)规范。若请求满足所有下述条件,则该请求可视为“简单请求”:
-
使用下列方法之一:
- GET
- POST
- HEAD
-
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
- 请求中没有使用 ReadableStream 对象。
预检请求
"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。
-
使用了下面任一 HTTP 方法:
- PUT
- DELETE
- CONNECT
- OPTIONS
- TRACE
- PATCH
-
人为设置了对 CORS 安全的首部字段集合之外的其他首部字段。该集合为:
- Accept
- Accept-Language
- Content-Language
- Content-Type (需要注意额外的限制)
- DPR
- Downlink
- Save-Data
- Viewport-Width
- Width
- Content-Type 的值不属于下列之一:
-
请求中使用了ReadableStream对象。
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
附带身份凭证的请求
一般而言,对于跨域 XMLHttpRequest 或 Fetch 请求,浏览器不会发送身份凭证信息。如果要发送凭证信息,需要设置 XMLHttpRequest 的某个特殊标志位。
XMLHttpRequest 的 withCredentials 标志设置为 true,从而向服务器发送 Cookies
HTTP首部字段
- Access-Control-Allow-Origin: *
* 允许所有源发起简单跨域请求
也可以是指定的域名 Access-Control-Allow-Origin: http://foo.example
- Access-Control-Allow-Methods: POST, GET, OPTIONS
允许使用的HTTP方法
- Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
允许使用设置额外的头部信息
token
- Access-Control-Max-Age: 86400
单位秒
在有效时间内,浏览器无须为同一请求再次发起预检请求
- Access-Control-Allow-Credentials: true
对于附带身份凭证的请求,服务器不得设置 Access-Control-Allow-Origin 的值为“*”。
对于携带cookie的跨域请求, Access-Control-Allow-Credentials为true可以将cookie下发给浏览器端,
否则不下发
- Access-Control-Expose-Headers
在跨域访问时,XMLHttpRequest对象的getResponseHeader()方法只能拿到一些最基本的响应头,Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,如果要访问其他头,则需要服务器设置本响应头。
Access-Control-Expose-Headers
头让服务器把允许浏览器访问的头放入白名单
Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
这样浏览器就能够通过getResponseHeader访问X-My-Custom-Header和 X-Another-Custom-Header 响应头了。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。