聊一聊常见的浏览器数据存储方案( 三 )

  • cookie 的操作是同步的;
  • 不能通过 web workers 来访问,但可以通过全局 window 对象访问 。
  • Cookie 通常用于会话管理、个性化以及跨网站跟踪用户行为 。我们可以通过服务端和客户端设置和访问 cookie 。Cookie 还具有各种属性,这些属性决定了在何处以及如何访问和修改它们,
    Cookie 分为两种类型:
    • 会话 Cookie:没有指定 Expires 或 Max-Age 等属性,因此在关闭浏览器时会被删除;
    • 持久性 Cookie:指定 Expires 或 Max-Age 属性 。这些 cookie 在关闭浏览器时不会过期,但会在特定日期 (Expires) 或时间长度 (Max-Age) 后过期 。
    (2)Cookie 操作下面先来看看如何访问和操作客户端和服务器上的 cookie 。
    ① 客户端(浏览器)客户端 JAVAScript 可以通过 document.cookie 来读取当前位置可访问的所有 cookie 。它提供了一个字符串,其中包含一个以分号分隔的 cookie 列表,使用 key=value 格式 。
    document.cookie;可以看到,在语雀主页中获取 cookie,结果中包含了登录的 cookie、语言、当前主题等 。
    同样,可以使用 document.cookie 来设置 cookie 的值,设置cookie也是用key=value格式的字符串,属性用分号隔开:
    document.cookie = "hello=world; domain=example.com; Secure";这里用到了两个属性 SameSite 和 Secure,下面会介绍 。如果已经存在同名的 cookie 属性,就会更新已有的属性值,如果不存在,就会创建一个新的 key=value 。
    如果需要经常在客户端处理 Cookie,建议使用像 js-cookie 这样的库来处理客户端 cookie:
    Cookies.set('hello', 'world', { domain: 'example.com', secure: true });Cookies.get('hello'); // -> world这样不仅为 cookie 上的 CRUD 操作提供了一个干净的 API,而且还支持 TypeScript,从而帮助避免属性的拼写错误 。
    ② 服务端(Node.js)服务端可以通过 HTTP 请求的请求头和响应头来访问和修改 cookie 。每当浏览器向服务端发送 HTTP 请求时,它都会使用 cookie 头将所有相关 cookie 都附加到该站点 。请求标头是一个分号分隔的字符串 。
    聊一聊常见的浏览器数据存储方案

    文章插图
     
    这样就可以从请求头中读取这些 cookie 。如果在服务端使用 Node.js,可以像下面这样从请求对象中读取它们,将获得以分号分隔的 key=value 对:
    http.createServer(function (request, response) {const cookies = request.headers.cookie;// "cookie1=value1; cookie2=value2"...}).listen(8124);如果想要设置 cookie,可以在响应头中添加 Set-Cookie 头,其中 cookie 采用 key=value 的格式,属性用分号分隔:
    response.writeHead(200, {'Set-Cookie': 'mycookie=test; domain=example.com; Secure'});通常我们不会直接编写 Node.js,而是与 ExpressJS 这样的 Node.js 框架一起使用 。使用 Express 可以更轻松地访问和修改 cookie 。只需添加一个像 cookie-parser 这样的中间件,就可以通过 req.cookies 以 JavaScript 对象的形式获得所有的 cookie 。还可以使用 Express 内置的 res.cookie() 方法来设置 cookie:
    const express = require('express')const cookieParser = require('cookie-parser')const app = express()app.use(cookieParser())app.get('/', function (req, res) {console.log('Cookies: ', req.cookies)// Cookies: { cookie1: 'value1', cookie2: 'value2' }res.cookie('name', 'tobi', { domain: 'example.com', secure: true })})app.listen(8080)(3)Cookie 属性下面来深入了解 cookie 的属性 。除了名称和值之外,cookie 还具有控制很多方面的属性,包括安全方面、生命周期以及它们在浏览器中的访问位置和方式等 。
    ① DomainDomain 属性告诉浏览器允许哪些主机访问 cookie 。如果未指定,则默认为设置 cookie 的同一主机 。因此,当使用客户端 JavaScript 访问 cookie 时,只能访问与 URL 域相同的 cookie 。同样,只有与 HTTP 请求的域共享相同域的 cookie 可以与请求头一起发送到服务端 。
    注意,拥有此属性并不意味着可以为任何域设置 cookie,因为这显然会带来巨大的安全风险 。此属性存在的唯一原因就是减少域的限制并使 cookie 在子域上可访问 。例如,如果当前的域是 abc.xyz.com,并且在设置 cookie 时如果不指定 Domain 属性,则默认为 abc.xyz.com,并且 cookie 将仅限于该域 。但是,可能希望相同的 cookie 也可用于其他子域,因此可以设置 Domain=xyz.com 以使其可用于其他子域,如 def.xyz.com 和主域 xyz.com 。


    推荐阅读