Skip to content

Cookie & Storage #27

@Calerme

Description

@Calerme

Cookie

  • Cookie 是保存在浏览器端的一段文本信息,一般不能超过 4kb
  • 每次访问网站,请求报文都会将与该网站对应的 cookie 附加在头部字段中

检测浏览器是否授受 cookie:

window.navigator.cookieEnabled // true | false

设置 Cookie

Cookie 一般通过 HTTP 响应报文进行设置,报文头部的Set-Cookie专门用来设置 Cookie,每一条Set-Cookie字段只能设置一个值。每一条Cookie必须写成键值对,且其中的分号、逗号和空格都必须进行转义。(如果是 JS,可使用 encodeURIComponent 函数)

HTTP/1.1 200 OK
Content-Type: text/html
Set-Cookie: user_name=John
Set-Cookie: user_state=login

Cookie 的属性

每一条 Cookie 还可以附带一些属性值,用来描述这条 Cookie 的过期时间、所属域名等。这些属性值必须以分号开头。

expires

该属性值的格式为 Date.toUTCString() 格式。

若不设置该属性或值为 null,Cookie 只会在当前会话(session)有效,浏览器窗口一旦关闭,即当前 Session 结束,该条 Cookie 就会删除。

domain

默认值为设定该 Cookie 的域名。

所设定的域名必须是当前域名的一部分。

 子域名可以在父域名中存取 cookie。

示例:

  • cookie_name=123; domain=example.com 该 Cookie 将存于 example.com 域名下
  • cookie_name=123; domain=.example.com example.com 的所有子域名将访问到

path

默认值为请求该 Cookie 的网页路径。

只有 path 属性匹配向用服务器发送的路径,Cookie 才会发送。这里的匹配不是绝对匹配,而是从根路径开始,只要 path 属性匹配发送路径的一部分,就可以发送。

示例:

  • Set-Cookie: user_id=iKr532NerudsleLerd; expires=Sun, 18 Mar 2018 01:02:08 GMT; domain=example.com; path=/

secure

指定该 Cookie 只能在 HTTPS 协议下发送到服务器。该属性没有值。

示例:

  • Set-Cookie: user_id=9527; secure

max-age

用来指定该 Cookie 的有效时间,单位为秒。

示例:

  • Set-Cookie: isLogin=true; max-age: 86400

HttpOnly

规定该 Cookie 不能被 JavaScript 读取。XMLHttpRequest 对象也无法包括这个 Cookie。

修改 Cookie

修改一条 Cookie 必须满足 keydomainpathsecure都匹配,才会将新的值覆盖到原 Cookie 上,否则会生成一条新的 Cookie。

通过 JavaScript 读取和添加 Cookie

读取

document.cookie 返回的是一条字符串

const cookieArray = document.cookie.split(';');
const cookieMap = new Map();

cookieArray.forEach( item => {
    cookieMap.set(...item.split('='));
});

设置

直接给document.cookie赋值就可以添加一条 Cookie,但一次只能添加一条 Cookie。

document.cookie = `user_id=1234567; expirs=${new Date.toUTCString()}; secure`;

同源政策

只要域名、端口相同,就可以共享 Cookie。

Web Storage

  • sessionStorage
  • localStorage

sessionStorage 和 localStorage 是浏览器提供本地存储的对象接口,挂载在这两个对象下的 API 完全相同,唯一区别是 sessionStorage 保存的数据用于浏览器的一次会话,当会话结束时(关闭该窗口),数据被清空;localStorage保存的数据会长期存在。

各浏览器对其存储上限为 2.5~10MB 之间。

Web storage 存储的数据的作用域为同域。

存入数据:

sessionStorage.setItem('key', 'value');
localStorage.setItem('key', 'value');

读取数据:

sessionStorage.getItem('key');
localStorage.getItem('key');

清除数据:

sessionStorage.removeItem('key');
localStorage.removeItem('key');

清空数据:

sessionStorage.clear();
localStorage.clear();

获取当前存储数据条数:

sessionStorage.length;
localStorage.length;

通过数字键值获取 key 值:

sessionStorage.key(0);
localStorage.key(1);

storage 事件

当存储数据发变化时,会触发 storage 事件。

window.addEventListener('storage', function (e) {
    console.log(e.key); // 发生变化的 key 值
    console.log(e.oldValue); // 更新前的值。如果值为新增,则该属性为 null
    console.log(e.newValue); // 当前值。如果操作为删除,该值为 null
    console.log(e.url); // 触发该 storage 事件的网页地址
});

sessionStorage 和 sessionCookie 的区别

如在https://example.com/a.html页面中分别存储一段 sesionStorage 和 cookie:

sessionStorage.setItem('test', 'Hello Data');
document.cookie = 'test=Hello%20Data; path=/';

然后在https://example.com/b.html页面中读取,

如果 b.html 是通过 a.html 中的链接打开的话,那么会话视为延续,此时 sessionStorage 和 cookie 都可以读到存入的值

sessionStorage.getItem('test');  // -> "Hello Data"
document.cookie // -> "test=Hello Data"

**如果 b.html 是直接在新标签中输入 url 打开的话,那么 sessionStorage 不会被读取到值,cookie 可以被读取到:

sessionStorage.getItem('test') //-> null
document.cookie // -> "test=Hello Data"

Cookie 跨域失败解决方案

项目填坑记-cookie

第三方 Cookie 及 Cookie 安全问题

这一次带你彻底了解 Cookie

参考

JavaScript 标准参考教程 - cookie

JavaScript 标准参考教程 - Web Storage

sessionStorage 与 session cookie 的区别

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions