了解了原理,要处理相关问题其实就很简单了
1. cookie如何进行设置?
其实解决方案很简单,我们可以自己写一个方法来对cookie
进行赋值,给所有(需要)的跨站的cookie
的值都追加不设置任何属性的值和设置None的值
function setCookie(cookieString, canCrossSite) {
document.cookie = `${cookieString}`;
if(canCrossSite) {
document.cookie = `${cookieString}; SameSite=None; Secure`;
}
}
2. 什么时候进行设置?
方案有了,那么应该在什么时候执行方法呢?
根据自己的了解,浏览器设置cookie
一般通过两个途径:通过Javascript API和请求头的Set-Cookie
2.1、通过Javascript API
通过Javascript API有两种方式,第一种是我们最常用的document.cookie=xxx
的方式,将cookie中放入需要的数据;另一种是通过Browser Extensions,可以获取到Cookie对象进行操作。
所以针对通过Javascript API设置的方式,我们只需要将以前通过document.cookie=xxx
的方式,修改为我们自定义的setCookie
方法来处理就可以了
2.2 通过请求Set-Cookie
设置
通过请求头中携带Set-Cookie
的头信息,可以完成后端请求给浏览器设置cookie
,设置以后对于需要跨站请求的cookie
就符合我们的预期,例如:
const http = require('http');
http.createServer((req, res) => {
res.setHeader('Set-Cookie', ['key5=page2; SameSite=None; Secure', 'key6=page2']);
res.setHeader('Access-Control-Allow-Origin', '*');
res.end('end');
}).listen(3001);
访问http://localhost:3001/index
以后可以发现,请求cookie
携带key6=page2
const http = require('http');
const fs = require('fs');
const server = http.createServer;
const options = {
key: fs.readFileSync('./key.pem'),
cert: fs.readFileSync('./cert.pem')
};
server(options, (req, res) => {
console.log(req.url)
if(req.url.indexOf('/index') > -1) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.end('index');
} else {
res.setHeader('Set-Cookie', ['key5=abc; SameSite=None; Secure;', 'key6=def;']);
res.setHeader('Access-Control-Allow-Origin', '*');
res.end('end');
}
}).listen(3001);
访问https://localhost:3001/index
以后可以发现,请求cookie
携带key5=page2
和key6=page2
前端也可以通过以上的方案按照自己的要求在异步请求结束的时候进行处理
function setCookieForSameSite() {
let cookies = document.cookie.split(';');
cookies.forEach(cookie => {
// 但是值可能存在多个等号,但是第一个等号是区分key和value的界限
// let [key, ...value] = cookie.trim().split('=');
setCookie(cookie, true);
});
}
PS:但是对于前端设置的情况需要注意,Set-Cookie
设置的cookie
仅仅针对请求的域名访问的时候增加携带cookie
,如果当前域名和请求的域名不一致,可以发现document.cookie
是无法获取到Domain
非当前域名的cookie
的(这一自己测试过一些例子,但是也没有特别清楚,如果有了解的可以一起探讨)
3. 其他
本来自己最开始的打算是给document.cookie
赋值的时候增加监听,希望在统一层面给所有的cookie
设置的时候都增加跨站属性,但是这样做存在两个问题:
第一,并非是所有的cookie
都需要进行跨站处理的,通常,我们需要跨站处理的信息通常都是一些登陆信息,而对于其他的cookie
信息设置跨站并没有很好的用处
第二,自己没有找到document.cookie
设置时候的钩子,虽然一开始觉得是否可以考虑使用Object.defineProperty
的方式
希望有更好解决方案的小伙伴能一起来讨论。