前端与Cookies的爱恨情仇,瞄一眼以免陷入深坑。
Cookies是什么
Cookies是一小段文本数据。
由于HTTP是无状态的,所以需要一个标识来追踪用户,Cookies于是应运而生。
Cookies有什么特点
前端时请求时会自动带上本域的合法Cookies,不同的http库可能需要自行加上额外参数。Cookies存在一些特定的属性用于更好的履行它的职责。
- k/v:一个键值对。
- domain:指定k/v生效的域名。
- path: 指定的路径。
- secure: 是否只允许在https环境下传输。
- expires:在多久后失效。
- http-only: 是否禁止脚本操作Cookies。
Cookies 和前端可能会擦出什么样的火花
同名 token 坑你没商量
由于 Cookie 只会被当前域名自动携带,所以各个网站都使用 token=xxx 作为k/v也毫无问题。
随着由于业务的发展,业务开始部署在类似于 xxx.domain.com、yyy.domain.com下,一旦某个后端服务 set-cookie 的时候,把 domain 写成了 .domain.com 和 xxx.domain.com,k/v却相同,噩梦就来了。由于前端是自动带上 cookies , 现在有多个同名 cookies 可以被浏览器携带上了,很有可能的情况就是,后端下发了一个合法的 cookies,但是浏览器自动携带了一个已经失效的 cookies,导致前后端流程走不通。
在我短暂的 Nodejs 服务端生涯中,我曾经在服务端接收到了两个同名的Cookies,但是一般的 cookie parse lib 只会给你解析一个。
webview 注入 token 可失效
前端开发很常见的一个场景就是帮客户端开发内嵌的H5页面,这个时候就需要客户端在 webview上传递 token。
但是如果客户端没有很好的处理 webview 跳转时的 Cookies 问题, 在经过2次跳转时,token 会注入失败 。
token 的 k/v 值请注意不要能被 Encode 编码改变
Cookies 是 headers上面传递。
服务端下发的 Cookies 是 A,A 从浏览器传过来的时候会被 urlencode,如果 A 里存在特殊字符,那么在服务端做校验时无法匹配,业务流程阻断。
前端删除 Cookies 不生效
前端清除 Cookies 看起来很简单,直接覆盖或者置空就好。但是请注意,如果你没有指定精确的 path、domain,很有可能你的操作全是骗自己,根本不会有任何反应。
某些平台其实是不支持 Cookies 的某些行爲
比如微信小程序?
Cookies 的的跨域和无法携带的问题
浏览器支持的 fetch 默认是不携带 Cookies 的,需要额外设置。
fetch(url, {
credentials: "include"
})
axios跨域携带 Cookies 需要设置
axios.get('http://happysooner.com', {withCredentials: true})
Cookies是必须的吗
不是的。
用于追踪用户,我们可以自定义其他的 Headers 属性去追踪。
Cookies 属于浏览器内置功能,比较成熟,对于整个系统来说,节约了很多额外的开发时间。
特别鸣谢
感谢以下用户对本文的支持与鼓励