1、前言javascript
今天遇到一个坑,浏览器请求数据的时候gg了。浏览器报错以下图:前端
由于请求头部设置了credentis mode is 'include', 从上面能够看出是Access-Control-Allow-Credentials这个响应必须设置为true。java
2、思考ios
第一反应前端没有设置过这个值啊?应该走默认才对吧?测试环境OK啊!axios
---------------------------------真是一万只野马狂奔而过啊-------------------------------------后端
因为以前没有遇到过这个问题,对这个也没怎么关注,因此排错慢了点。
api
后面查了一下资料,而后回归一下代码,oh my god! 其余前端宝宝在请求中设置了这个:(由于是合做开发,我也没有注意这个,此处没有甩锅的ys)跨域
config.withCredentials = true
那么前端设置上面这个有啥用?那为何加了就报错呢?后台难道没有配合设置对应相应头部吗?浏览器
【后续想起】估计是后台小哥哥说过:“前端最好给后台传cookie和token” 这句话吧,致使前端小哥哥加上了这个设置,不事后面后台并无设置cookie。因此不必加啊,这就是信息不对称致使结果吧。服务器
3、原理及处理方法
一、标准的跨域请求是不会发送cookie等用户认证凭据的,XMLHttpRequest 2的一个重要改进就是提供了对授信请求访问的支持。也就是说,若是发生跨域请求,又想携带cookie到服务器,前端请求和后端响应都必须设置:
二、前端请求:
var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://www.xxx.com/api'); xhr.withCredentials = true; xhr.onload = onLoadHandler; xhr.send();
或者在axios请求配置中设置:
三、服务端响应头:
Access-Control-Allow-Credentials: true
若是服务端不设置该响应头,浏览器会报错,固然响应会被忽略不可用;
同时,服务端需指定一个域名(Access-Control-Allow-Origin:www.xxx.com),而不能使用泛型(Access-Control-Allow-Origin: *)否则即便设置了该头部,cookie开始不能转到服务器。
4、总结
一、本次错误是由于前端配置了Credentials:true,可是浏览器没有设置Access-Control-Allow-Credentials: true,且响应是Access-Control-Allow-Origin:*;
二、若是在跨域中但愿浏览器能携带cookie到服务器,先后端都应该设置Credentials的值为true, 且Access-Control-Allow-Origin就不能设为星号,必须指定明确的,与请求网页一致的域名。,否则cookie仍是不能携带过去;
三、Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其余域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也没法读取服务器域名下的Cookie;
四、若是服务器不要浏览器发送cookie,先后端都不设置这个字段就行了。