唯品秀前端博客

withCredentials:默认情况下,跨源请求不提供凭据(cookie、HTTP认证及客户端SSL证明等)。前端通过将withCredentials属性设置为true指定某个请求应该发送凭据

一、cors跨域

注意,如果端口不同的话,服务器是无法通过接口主动往客户端种下cookie,要么你先请求一个同源的接口让服务端种下cooie,或者前端可以通过登录接口拿到cookie手动种下,后续接口请求只需要withCredentials参数为true就可以自动携带给后端,具体案例

参数中设置

1
2
3
4
5
6
7
8
9
10
11
12
// 发送跨域请求
crossButton.onclick = function () {
  axios({
    method: "get",
    withCredentials: true, // ++ 新增
    url: "http://test.weipxiu.cn:8003/anotherService",
  }).then((res) => {
    console.log(res);
  });
};
true:在跨域请求时,会携带用户凭证
false:在跨域请求时,不会携带用户凭证;返回的 response 里也会忽略 cookie

main.js中设置

1
2
Vue.prototype.$axios = axios;
axios.defaults.withCredentials = true;

注意:当配置了 withCredentials = true时,必须后端配置增加 response 头信息Access-Control-Allow-Origin,且必须指定域名,而不能指定为*
如果后端需要带cookie过去,前端需要设置为true

1
2
3
4
5
6
7
8
9
10
11
12
13
// 服务端需要配置:
// 响应头表示是否可以将对请求的响应暴露给页面
Access-Control-Allow-Credentials: true
// 允许跨域操作的具体域名
Access-Control-Allow-Origin: "http://localhost:8080"
// 允许跨域的HTTP方法
Access-Control-Allow-Methods: ["GET","POST","DELETE"]
// 列出将会在正式请求的 Access-Control-Expose-Headers 字段中出现的首部信息
Access-Control-Allow-Headers: ["Content-Type", "Authorization", "Accept"]

// 前端需要配置:
// 表示跨域请求时是否需要使用凭证
axios.defaults.withCredentials = true

二、前端代理

1
2
3
4
5
6
7
8
proxy: {
  '/api': {
    target: 'http://www.weipxiu.com', // 代理目标地址,有端口的带端口
    changeOrigin: true, // 开启代理,在本地创建一个虚拟服务器
    logLevel: 'debug', // node终端可以查看转发过程
    rewrite: (path) => path.replace(/^\/api/, ''), // 配置重写规则,将接口中的/api去掉
  },
},

三、前台js操作cookie的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function getCookie(cname) {
  var name = cname + "=";
  var ca = document.cookie.split(';');
  for(var i = 0; i < ca.length; i++) {
    var c = ca[i];
    while(c.charAt(0) == ' ') c = c.substring(1);
    if(c.indexOf(name) == 0) return c.substring(name.length, c.length);
  }
  return "";
}
 
 
function setCookie(cname, cvalue, exdays) {
  var d = new Date();
  d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
  var expires = "expires=" + d.toUTCString();
  document.cookie = cname + "=" + cvalue + "; " + expires + ";path=/";
}
 
 
//调用示例
setCookie("name", "value", "expire");
 
getCookie("xxx");

四、别人不知道的秘密

这个秘密经过一下午测试得到验证,假设我们ip地址相同但端口不同,例如127.0.0.1:3000和127.0.0.1:888; 那么这两个ip的cookie是可以共享的,但经过我通过域名测试,并不可以

二级域名cookie共享同上,解释下二级域名cookie共享,假设我们有一个一级域名.com,对应两个二级域名a.weipxiu.com/b.weipxiu.com,此时我希望在a.weipxiu.com登录后去请求b.weipxiu.com的接口,b下面可以拿到a的cookie,在这里我们需要在a下面配置domain,例如:/p>

1
2
3
4
5
// 设置`cookie`
app.get("/login", (req, res) => {
  res.cookie("user", "lijun", { maxAge: 2000000, httpOnly: true,  domain:"weipxiu.com" }); // 注意domain设置在相同的二级域名上
  res.json({ code: 0, message: "登录成功" });
});

通过上面方式网上都说这样就实现了二级域名cookie共享,实际上也只是通过ip地址可以直接访问到,例如在a登录后,直接浏览器地址栏打开b的接口http://b.weipxiu.cn:8000/user,服务端接口内容如下:

1
2
3
app.get("/user", (req, res) => {
  res.json({ code: 0, user: req.headers.cookie});
});

这样通过地址栏访问确实可以直接拿到a设置的cookie,但是我们前端开发实际肯定是在ajax中请求,例如:

1
2
3
4
5
6
// 获取cookie
crossButton.onclick = function () {
  axios.get("http://b.weipxiu.cn:8000/user", {}).then((res) => {
    console.log(res);
  });
};

很抱歉,前端通过ajax去请求,啥也拿不到,这主要是浏览器自身做了拦截,解决方案自然还是按照cors或者代理方式来,在这里只是记录下网上说的二级域名cookie共享是怎么回事,大家几乎都没提到实际应用这个问题

本站所有文章、图片、资源等如无特殊说明或标注,均为来自互联网或者站长原创,版权归原作者所有;仅作为个人学习、研究以及欣赏!如若本站内容侵犯了原著者的合法权益,可联系我们进行处理,邮箱:343049466@qq.com
赞(0) 打赏
标签:

上一篇:

下一篇:

相关推荐

0 条评论关于"axios.defaults.withCredentials跨域携带cookie"

表情

最新评论

    暂无留言哦~~
谢谢你请我吃鸡腿*^_^*

支付宝扫一扫打赏

微信扫一扫打赏