昨天遇到了线上环境cookie无法储存的问题,开发环境下由于使用了create-react-app的代理请求所以开发环境下并没有出现这个问题,上线之后发现响应头中虽然显示设置了cookie,然而Application中cookie并没有设置成功。
经过一番查询,axios发起请求是不会携带cookie的 axios文档
所以需要全局设置
axios.defaults.withCredentials = true
node后台也需要相应的设置
app.use('*',function (req, res, next) {
//*表示任意域名都可以访问,这样写不能携带cookie了,所以要写固定域名。
res.header('Access-Control-Allow-Origin', 'http://localhost:8070');
res.header('Access-Control-Allow-Credentials', true); // 允许服务器端发送Cookie数据
//res.header('Access-Control-Allow-Origin', 'www.baidu.com'); //这样写,只有www.baidu.com 可以访问。
res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');//设置方法
if (req.method == 'OPTIONS') {
res.send(200); // 意思是,在正常的请求之前,会发送一个验证,是否可以请求。
}
else {
next();
}
});
express使用cors模块的写法
var cors = require('cors');
app.use(cors({
origin: 'http://localhost:8070',
credentials: true // 是否带cookie
}));
原生ajax和jquery的写法
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://xxxx.com/demo/b/index.php", true);
xhr.withCredentials = true; //支持跨域发送cookies
xhr.send();
$.ajax({
type: "POST",
url: "http://xxx.com/api/test",
dataType: 'jsonp',
xhrFields: {
withCredentials: true
},
crossDomain: true,
success:function(){
},
error:function(){
}
})
fetch的写法
fetch(url, {
method: 'GET',
headers: myHeaders,
//携带cookie
credentials: "include"
})
然而这几种方法都试了,但是cookie依然没有设置成功,想来想去问题也只能出在服务器端了,继续查询终于发现简书的一篇博客正好解决了这个问题,下面引用他的文章,由于经过了反向代理,导致Domino的Response中Cookie的Domain属性,与反向代理的域名不一致,Cookie的Domain属性,仍然是Domino服务器的域名。手机端拿到Cookie之后,再次进行请求的话,请求是发往反向代理的,浏览器认为之前拿到的Cookie不属于反向代理,所以Request的时候,不会把Cookie带上,导致认证不能通过。
解决方案
location / {
proxy_cookie_domain domino_server nginx_server;
}
果然在nginx配置中加了proxy_cookie_domain之后cookie的客户端的cookie就可以正常读取了。