cookie 的一点整理

220 阅读6分钟

cookie 的一点整理

背景

在整理 cookie 相关的知识的时候,查阅了许多文章,但是很多知识都是零零散散的。于是打算自己写一篇,在写的过程中参考了几篇写得比较好的文章,把相关的知识点串在一起,参考的文章见最后。

什么是 cookie

可以把 cookie 理解为存储在浏览器的特殊文本数据,cookie 本质是一段文本数据,但因为其独特的作用,所以在使用的过程中有很多特殊的地方,接下来我们从 cookie 的作用开始讲起,看看 cookie 有什么特殊的地方。

cookie 的作用

一般的网页的数据是通过 http 协议传输的,因为 http 协议是无状态的(每次请求都是一次独立的连接),导致网页并不能记住用户的一些状态,比如用户第一次登录账号后关闭网页,第二次进入网页仍然需要登录账号。但这显然不是我们想要的,于是有了一些变通的方法,借助 cookie 和 session 来保存网页的状态。

小结一下:cookie 的作用是保存网页的状态

如何使用 cookie

本小节讲解 cookie 的运行流程,以及如何使用 cookie

cookie 运行的流程

cookie 按域名存储,默认情况下不能跨域名访问其他域名存储的 cookie。当页面发送请求时,若当前页面访问范围内存在 cookie,则将所有 cookie 取出来放在请求头中一起提交给服务端,这样服务端就可以获取到浏览器存储的 cookie 了;而且当服务端返回时也可以在响应头中加上 set-cookie 字段,设置新的 cookie,当浏览器接到返回后,会根据服务端设置的 cookie 更新浏览器中的 cookie。

如何设置 cookie

设置 cookie 有两种方式:

  • 通过 dom 接口设置
  • 通过服务端响应头设置

使用 dom 设置 cookie

没有设置 HttpOnly 才能使用 js 操作 cookie

借助 document.cookie 对象可以很方便的设置 cookie 源码

function setCookie() {
  var cookieNameElement = document.getElementById('cookieName')
  var cookieValueElement = document.getElementById('cookieValue')
  var d = new Date()

  d.setTime(d.getTime() + (24*60*60*1000))
  var expires = "expires=" + d.toGMTString()
  document.cookie = cookieNameElement.value + "=" + cookieValueElement.value + ";" + expires

}

若想删除一个 cookie 只需要将 expires 设置为过去的某个时间即可

使用服务端响应头设置 cookie

通过服务端设置 cookie 需要在 responseHeader 中添加 set-cookie

access-control-allow-credentials: true
access-control-allow-origin: https://juejin.cn
content-encoding: gzip
content-type: application/json; charset=utf-8
date: Tue, 16 Feb 2021 10:11:34 GMT
eagleid: 700d6ba116134702942147755e
server: Tengine
server-timing: inner; dur=54
timing-allow-origin: *
...
// 通过set-cookie设置cookie
set-cookie: name=user; Path=/; HttpOnly

如何获取 cookie

这里只展示如何通过 dom 获取 cookie,服务端获取 cookie 的方式和服务端框架有关,请自行查找相关资料 源码

function getCookies() {
  var cookieContent = document.getElementById('cookie-content')
  cookieContent.innerText = document.cookie
}

cookie 的一些特性及其用法

cookie 的属性

属性名属性值作用
namestringCookie 的名称和值,名称一旦创建便不可更改, 值若为 Unicode 字符,需要为字符编码。值如果为二进制数据,则需要使用 BASE64 编码
maxAgenumberCookie 失效的时间,单位秒。如果为整数,则该 Cookie 在 maxAge 秒后失效。如果为负数,该 Cookie 为临时 Cookie,关闭浏览器即失效,浏览器也不会以任何形式保存该 Cookie。如果为 0,表示删除该 Cookie。默认为-1。
Expirestime失效的时间点 是一个具体的时间,当到达时间后 cookie 失效,可设置一个过去时间来删除 cookie
secureboolean该 Cookie 是否仅被使用安全协议传输。安全协议。安全协议有 HTTPS,SSL 等,在网络上传输数据之前先将数据加密。默认为 false
pathstringCookie 的使用路径。如果设置为“/sessionWeb/”,则只有 contextPath 为“/sessionWeb”的程序可以访问该 Cookie。如果设置为“/”,则本域名下 contextPath 都可以访问该 Cookie。注意最后一个字符必须为“/”。
domainstring可以访问该 Cookie 的域名。如果设置为“.google.com”,则所有以“google.com”结尾的域名都可以访问该 Cookie。注意第一个字符必须为“.”
httponlybooleancookie 中设置了 HttpOnly 属性,那么通过 js 脚本将无法读取到 cookie 信息,这样能有效的防止 XSS 攻击,窃取 cookie 内容,这样就增加了 cookie 的安全性

cookie 的大小和数量限制

ie6ie7/ie8operafirefoxsafarichrome
cookie 个数每个域为 20 个每个域为 50 个每个域为 30 个每个域为 50 个没有个数限制每个域为 53 个
cookie 总大小4095byte4095byte4096byte4097byte4097byte4097byte

如何判断浏览器禁用了 cookie

function CookieEnable(){
  var result = false;
  if (navigator.cookiesEnabled) return true;

  document.cookie = "testcookie=yes;";

  var cookieSet = document.cookie;

  if (cookieSet.indexOf("testcookie=yes") > -1) result = true;

  document.cookie = "";

  return result;
}

if(!CookieEnable()){
  alert("对不起,您的浏览器的Cookie功能被禁用,请开启");
}

cookie 的缺陷

  • 可能会被用户禁止cookie功能,或者用户删掉cookie
  • 能存储的数据比较小
  • 使用文本存储,安全性不高(不要存储敏感数据到cookie)

与 session 的区别

session也可以用来保存网页的状态,session和cookie经常被拿来比较,它们之间有以下几点区别

  • cookie保存在浏览器端,session保存在服务端
  • cookie可以通过请求头在服务端和浏览器端之间传递,而session不能来回传递
  • cookie不够安全,容易被伪造,session放在服务器,不容易拿到
  • cookie能存储的数据比较小一般为4k,且创建的数量有限制;而session的大小服务器并没有做限制

总结

cookie本质是存储在浏览器中的一段特殊的文本数据,可以使用dom接口以及http头信息对其进行操作,cookie有domain、path等属性,可以通过设置属性灵活地控制cookie的访问权限,比如在a域名下设置b域名访问,但a域名不能访问的cookie。在使用过程中需要注意cookie的缺陷,合理地利用好cookie的特性,一定能给你的工作带来很大的帮助。

参考

HTML5 学习笔记(二十九):Cookie 和 Session

JavaScript Cookie

HTTP State Management Mechanism

js 判断用户是否禁用了 cookie