跨域
同源策略
跨域问题其实就是浏览器的同源策略所导致的。
协议、主机、端口 都相同,即为同源。
同源策略限制内容有:
- Cookie、LocalStorage、IndexedDB 等存储性内容
- DOM 节点
- AJAX 请求发送后,结果被浏览器拦截了
但是 img、link、script 标签是允许跨域加载资源
两种请求
简单请求
请求方法是以下三种之一:
- HEAD
- GET
- POST
头信息仅限以下字段:
- Accept
- Accept-Language
- Content-Language
- Content-Type
- text/plain
- multipart/form-data
- application/x-www-form-urlencoded
非简单请求
凡是不同时满足以上条件,均属于非简单请求。
正式请求前会发一次 OPTIONS
类型的查询请求,称为 预检请求
,询问服务器是否支持网页所在域名的请求,以及可以使用哪些头信息字段。只有收到肯定的答复,才会发起正式请求,否则报错。
CORS
CORS(Cross-Origin Resource Sharing),跨源资源共享
响应头
- Access-Control-Allow-Origin
指示响应的资源是否可以被给定的来源共享。 - Access-Control-Allow-Credentials
指示当请求的凭证标记为 true 时,是否可以公开对该请求响应。 - Access-Control-Allow-Headers
用在对预检请求的响应中,指示实际的请求中可以使用哪些 HTTP 标头。 - Access-Control-Allow-Methods
指定对预检请求的响应中,哪些 HTTP 方法允许访问请求的资源。 - Access-Control-Expose-Headers
通过列出标头的名称,指示哪些标头可以作为响应的一部分公开。 - Access-Control-Max-Age
指示预检请求的结果能被缓存多久。
请求头
- Access-Control-Request-Headers
用于发起一个预检请求,告知服务器正式请求会使用哪些 HTTP 标头。 - Access-Control-Request-Method
用于发起一个预检请求,告知服务器正式请求会使用哪一种 HTTP 请求方法。 - Origin
指示获取资源的请求是从什么源发起的。
跨域时的Cookie
CORS 请求默认不发送 Cookie 和 HTTP 认证信息。
如果要把 Cookie 发送到服务器:
- 要服务器同意
- 设置 Access-Control-Allow-Credentials: true 响应头
- 相应的使用中间件设置 credentials
- 客户端同意
- xhr: withCredentials = true
- fetch :credentials: 'include'
如果要发送 Cookie,Access-Control-Allow-Origin
就不能设为 *
,必须指定明确的、与请求网页一致的域名。同时,Cookie 依然遵循同源策略。
参考
- 跨源资源共享(CORS) - MDN
- 浏览器的同源策略 - MDN
- CORS - MDN
- CORS 详解,终于不用担心跨域问题了 - 阿里云开发者社区
- 九种跨域方式实现原理(完整版) - 掘金