带 credentials 的 CORS 请求
Credentials 与 CORS
Credentials(凭证)
可以是 cookies, authorization headers 或 TLS client certificates。CORS
请求默认不发送 Credentials。
如何让 CORS 请求发送 Credentials?
如果要让带 credentials 的 CORS 请求成功,前后端都需要配置。否则,即使服务器同意发送 Cookie,浏览器也不会发送。或者,服务器要求设置 Cookie,浏览器也不会处理。
Cookie 依然遵循同源政策,只有用服务器域名设置的 Cookie 才会上传,其他域名的 Cookie 并不会上传
配置
后端配置:Access-Control-Allow-Credentials
header;
前端配置:
XHR 配置 withCredentials
或 Fetch request 配置 credentials
;
Access-Control-Allow-Credentials
它的值是一个布尔值,表示是否允许发送 Cookie。默认情况下,Cookie 不包括在 CORS 请求之中。设为true
,即表示服务器明确许可,Cookie 可以包含在请求中,一起发给服务器。
如果服务器不要浏览器发送 Cookie,删除该字段即可。
Request.credentials
credentials
是Request
接口的只读属性,用于表示用户代理是否应该在跨域请求的情况下从其他域发送 cookies。有三个可选值:
omit
: 从不发送cookies。same-origin
: 只有当URL与响应脚本同源才发送 cookies、 HTTP Basic authentication 等验证信息。include
: 不论是不是跨域的请求, 总是发送请求资源域在本地的 cookies、 HTTP Basic authentication 等验证信息。
XMLHttpRequest.withCredentials
withCredentials
是一个Boolean
类型,如果是 true, 执行跨域请求时会带上 Credentials,否则不会携带。默认值是false。
- 如果在发送来自其他域的XMLHttpRequest请求之前,未设置
withCredentials
为true,那么就不能为它自己的域设置cookie值。 - 通过设置
withCredentials
为 true 获得的第三方 cookies,将会依旧享受同源策略,不能被通过 document.cookie 或者从头部相应请求的脚本等访问。 - 在同一个站点下使用
withCredentials
属性是无效的。它永远不会影响到同源请求。
例子
后端允许 credentials:
Access-Control-Allow-Credentials: true
前端使用带 credentials 的 XHR 请求:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/', true);
xhr.withCredentials = true;
xhr.send(null);
前端使用带 credentials 的 Fetch 请求:
fetch(url, {
credentials: 'include'
})
当 credentials 是 include 时,Access-Control-Allow-Credentials 必须设置为 true; 当 credentials 是其他值时,可以不设置Access-Control-Allow-Credentials。
设置 credentials: 'include' 不生效
现在设置 credentials 的 Fetch 请求如下:
fetch(url, {
credentials: 'include'
})
实际出去的请求:
fetch(url, {
credentials: 'omit'
})
为什么设置的include
无效,反而被修改为 omit
?
经检查发现,当前页面协议为 http
,请求 url 协议是 https
,如果两个协议不同,则请求时主动修改 credentials 为 'omit'。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。