今天在上线的小程序中遇到一个bug,关于cookie的问题 然后记录下来,弄懂了一下cookie是怎么运作的,
首先说这个bug是怎么来的;
分析:
我的小程序中封装了微信的请求,本身微信的请求是不支持cookie,需要经过处理才能在请求头里带上cookie;所以经过封装的request如下:
/* 自己封装的请求方法,用法同wx.request */
export function request(obj) {
if (!obj.noLoading) wx.showLoading();
/* 可以自传服务器地址也可以用默认服务器 */
// var appInst = getApp();
// var headers=getApp().globalData.header.Cookie = 'JSESSIONID=' + store.state.token;
// var header = getApp().globalData.header;
var header = {
'content-type': 'application/json; charset=utf-8',
'cookie': wx.getStorageSync("sessionid")
};
let url = obj.url.indexOf('http') == -1 ? config.baseUrl + obj.url : obj.url;
// let url = urlType === 'scan' ? config.productUrl+ obj.url : config.baseUrl + obj.url ;
wx.request({
url: url,
method: obj.method || "GET",
// data: Object.assign(obj.data, {loginInfo: store.state.loginInfo}),
data: obj.data,
// header: obj.header || {
// 'content-type': 'application/json', // 默认值
// 'JSESSIONID': store.state.token
// },
header: header,
success: (res) => {
wx.hideLoading();
if (res.statusCode !== 200) {
wx.showToast({
title: '服务器异常...',
icon: 'none',
duration: 2000,
success: () => {
console.log('服务器异常');
setTimeout(() => {
//要延时执行的代码
wx.redirectTo({
url: '/pages/login/main'
});
}, 500) //延迟时间
}
})
} else {
obj.success(res);
//微信授权token失效, 请重新登录
var cookie = res.header["Set-Cookie"];
if (cookie != null) {
wx.setStorageSync("sessionid", res.header["Set-Cookie"]);
}
if (res.data.code == 403) {
wx.removeStorage({key: "sessionid",success(res) {console.log(res);}});
wx.showToast({
title: res.data.errMsg,
icon: 'none',
duration: 2000,
success: () => {
setTimeout(() => {
//要延时执行的代码
wx.redirectTo({
url: '/pages/login/main'
});
}, 500) //延迟时间
}
})
// wx.redirectTo({
// url: '/pages/login/main'
// });
}
}
},
fail: (res) => {
wx.hideLoading();
wx.showToast({
icon: 'none',
duration: 3000,
title: '网络开小差,请稍后重试'
});
if (obj.fail) obj.fail(res);
},
complete: res => {
if (obj.complete) obj.complete(res);
}
});
}
这段代码就是添加cookie用的
然后再说流程;
我这里下方的图片有四个接口;
流程是 先调用登陆接口;我这边在调用接口的时候会给后台传入一个cookie:
图片上可以看到 Request Headers中的cookie参数值是空的, 对,它就是空的,
因为这个Request Headers 是我们前端需要传给后台的参数,一开始调用登陆的时候是没有cookie这个值的,那么后台接收到请求之后,一看 cookie是空的,好,既然是空的,那我后台就给你一个cookie,那这个cookie 我们在哪儿看呢?那就在 Response Headers中,这个Response Headers是后台返回给我们的数据,你是不是发现其中有一个
Set-Cookie:JSESSIONID=BFE906BE407F3F740B6B308F2D2F0480; Path=/; HttpOnly
对了 这就是后台返给我们前端的参数,那我们这边拿到这个cookie 存下来,下次请求接口的时候需要带上这个cookie 传给后端,保持我们的这个登陆状态。那么这个逻辑就完了。
那接下来说bug:
看我图片中第一个接口 登陆接口 后台返回了一个 set-cookie 我们拿到这个cookie 去请求下面的第二个请求
其实我图上说的已经很清楚了,你看下第二个接口我发送给后端的接口中 cookie 和上面 登陆的时候后台返给我的一摸一样呢,是的 它就是一样的。没有问题。就是这个操作你调用接口 就是反复始终,除非这个cookie过期了 或者你重新登陆了 那么这个cookie就变了,但是不影响程序逻辑,
所以第三个接口也是一样的,所以我们就不看第三个接口了,
直接看第四个接口;
这个接口是腾讯地图调用的接口;
你看我同样是用了我封装好的网络请求方法;我传入了cookie 但是腾讯不认识你这个cookie,好,它就会下发一个新的cookie给你,为什么它不认识,因为它不是我们后台 是腾讯后台,所以肯定不认识我们的cookie,所以下发了一个新的 然而我拿到它这个新的cookie。
然后我拿到新的cookie 我就会通过我封装好的请求方式去保存这个cookie,接下来我又调用了第四个接口,这个是我们后端的接口,
你看 我传入后台的cookie 变成了腾讯返回给我的cookie 传过去之后 后端不认识这个 然后又给了一个新的给我,然后我拿到这个新的 去请求其他接口的时候 就提示失效了 要我重新登陆。,但是只要我不去调用腾讯的定位请求接口 这个cookie还是可以用的,但是只要一旦调用 腾讯的定位请求接口 这个cookie就会变化,就需要我重新登陆。所以 我的做法是
在调用腾讯的定位请求接口的时候 就直接使用微信原生的这个wx.request请求
这样就不会覆盖我们本来的cookie了。问题就直接解决/