前提
协议相同,域名相同,端口号不同,但是在往cookie存放相同的一个字段token时,会发现 前一个存放的token,会被后一个token 覆盖掉
问题二:同域名下,不同的二级域名清空Cookie导致同域名的Cookie全部清空,如何解决??
之前学习过同源策略,提及到:同一协议、同一域名、统一端口号,当其中一个不满足时,请求会发生跨域问题。
但是在实际项目中,遇到过本地启动两个项目遇到过 “协议相同,域名相同,端口号不同,但是在往cookie存放相同的一个字段token时,会发现 前一个存放的token,会被后一个token 覆盖掉” 这个问题。
本地启动了两个项目,地址分别是
两个项目除了端口其他相同,在A、B两个项目中分别设置cookie 中的token,值为1、2,先设置项目A为1,再设置项目B为2,发现几个现象:
- 设置项目A中cookie token=1, B项目暂时未设置, 但是可以在项目B中获取token = 1
- 设置项目A中 token = 1, 项目B中 token =2 ,在A获取token,发现结果 token = 1
结论
Cookie是不区分端口号的,如果Cookie名相同,会自动覆盖,并且读取是相同的数据。
后续应该想办法避免,例如设置独立的token,或者不同的域名。
另外附有setCookie 和 getCookie
import { Base64 } from 'js-base64';
/**
*
* @param name cookie名称
* @param value cookie 对应的 value
* @param time 设置cookie的有效时长
*/
export const setCookie = (name, value, time) => {
const times = time || 30 * 30 * 48;
const d = new Date();
d.setTime(d.getTime() + (times * 60 * 1000));
document.cookie = `${name}=${Base64.encode(value)};expires=${d.toGMTString()};path=/`;
};
/**
* 获取cookie
* @param name
*/
export const getCookie = (name) => {
const ca = document.cookie.split('; '); // ca格式例如["name=xiaoming", "age=25"]
let str;
for (let i = 0; i < ca.length; i += 1) {
if (name === 'token') {
if (ca[i].startsWith('token=')) {
const c = ca[i].split('token=');
str = Base64.decode(c[1]);
return str;
}
}
const c = ca[i].split('='); // c格式例如["name", "xiaoming"]
if (c[0] === name) {
str = Base64.decode(c[1]);
return str;
}
}
return str;
};
问题二解决方案:
偶然间注意到cookie的path属性,在set中,设置path属性,实践测试发现,设置这个属性之后,不同的项目虽然域名相同,但是在cookie中不会出现串联的现象,在清空cookie中,也不会出现全部清空的问题。
export const setCookie = (key, value, time) => {
const cookies = new Cookies();
const expires =
time ||
new Date(
moment()
.add(30, 'days')
.format()
); // 过期时间,30天
cookies.set(key, encrypt(value), {
path: '/**',
expires,
});
};
一、什么是跨域?
当一个请求url的协议、域名、端口三者之间任意一个与当前页面的url不同时即为跨域。
二、解决跨域的方法
1、 通过jsonp 解决跨域
JSONP 是服务器与客户端垮源通信的的常用方法。最大特点就是简单适用,兼容性好,缺点是只能get请求,不支持post请求。
核心思想:网页通过添加一个<script > 元素,向服务器请求JSON 数据,服务器收到请求后,将数据放到一个指定名字的回调函数的参数位置传送回来。
- 原生实现:
<script src="http://test.com/a.js?callback=dosomething"></script>
<script text="text/javaScript">
function dosomething (res) {
console.log(res)
}
</script>
- jQuery ajax
$.ajax({
url: 'http://www.test:8080/login',
type: 'get',
dataType: 'jsonp',
jsonpCallback: 'callBack',
data: {},
})
- Vue.js
this.$http.jsonp('http://www.test:8080/login', {
params: {},
jsonp: 'callBack',
}).then((res) => {
console.log(res);
})