XingYun blog
  • JS基础

    • 图解js原型链
    • JS Event Loop
    • 对象的底层数据结构
    • 让你的JavaScript代码简单又高效
    • 函数参数按值传递
    • 判断数据类型
    • 浮点数精度问题和解决办法
    • 常用方法snippet
    • 实现Promise
    • 防抖和节流
    • 巧用sort排序
  • CSS && HTML

    • CSS也需要性能优化
    • class命名规范
    • em、px、rem、vh、vw 区别
    • CSS揭秘阅读笔记
  • 浏览器

    • 浏览器是如何渲染页面的
    • 重排和重绘
    • BOM浏览器对象模型
    • DOM事件
    • 浏览器存储
  • 数据结构

    • JS实现链表
    • JS实现栈与栈应用
    • JS实现常见排序
    • 哈夫曼编码
    • MD5算法
  • vue原理浅析

    • Vue虚拟dom与Diff算法
    • 前端打包文件的缓存机制
    • vue数组为什么不是响应式
    • v-for为什么不能用index做key
  • 前端工程化

    • 浏览器是如何渲染页面的
    • 前端打包需要gzip压缩吗
    • 前端打包文件的缓存机制
    • webpack loader和plugin
  • 轮子&&组件库

    • 实现水波浪进度球
  • 文字转语音mp3文件
  • 文件上传前后端实现
  • moment.js给定时间获取自然月、周的时间轴
  • 实现文件上传功能
  • 批量下载照片
  • leaflet改变坐标原点
  • 网络

    • 有了MAC地址 为什么还需要IP地址
    • 为什么IP地址老是变
    • 我们为什么需要IPV6
    • TCP与UDP
  • 计算机组成原理

    • ASCII、Unicode、UTF-8和UTF-16
  • VSCode

    • VSCode图片预览插件 Image preview
    • rsync:linux间的高效传输工具

XingYun

冲!
  • JS基础

    • 图解js原型链
    • JS Event Loop
    • 对象的底层数据结构
    • 让你的JavaScript代码简单又高效
    • 函数参数按值传递
    • 判断数据类型
    • 浮点数精度问题和解决办法
    • 常用方法snippet
    • 实现Promise
    • 防抖和节流
    • 巧用sort排序
  • CSS && HTML

    • CSS也需要性能优化
    • class命名规范
    • em、px、rem、vh、vw 区别
    • CSS揭秘阅读笔记
  • 浏览器

    • 浏览器是如何渲染页面的
    • 重排和重绘
    • BOM浏览器对象模型
    • DOM事件
    • 浏览器存储
  • 数据结构

    • JS实现链表
    • JS实现栈与栈应用
    • JS实现常见排序
    • 哈夫曼编码
    • MD5算法
  • vue原理浅析

    • Vue虚拟dom与Diff算法
    • 前端打包文件的缓存机制
    • vue数组为什么不是响应式
    • v-for为什么不能用index做key
  • 前端工程化

    • 浏览器是如何渲染页面的
    • 前端打包需要gzip压缩吗
    • 前端打包文件的缓存机制
    • webpack loader和plugin
  • 轮子&&组件库

    • 实现水波浪进度球
  • 文字转语音mp3文件
  • 文件上传前后端实现
  • moment.js给定时间获取自然月、周的时间轴
  • 实现文件上传功能
  • 批量下载照片
  • leaflet改变坐标原点
  • 网络

    • 有了MAC地址 为什么还需要IP地址
    • 为什么IP地址老是变
    • 我们为什么需要IPV6
    • TCP与UDP
  • 计算机组成原理

    • ASCII、Unicode、UTF-8和UTF-16
  • VSCode

    • VSCode图片预览插件 Image preview
    • rsync:linux间的高效传输工具
  • leaflet改变坐标原点
  • 补间动画gsap与tween
  • 文字转语音mp3文件
  • JavaScript引入
  • JavaScript高级程序设计阅读笔记
  • Javascript函数参数按值传递传递
  • JS防抖和节流
  • 手写JS常用方法
  • 手写Promise
  • JS Event Loop
  • 重排和重绘
  • em、px、rem、vh、vw 区别
  • css也需要性能优化
  • 图解 js 原型链
  • js函数参数按值传递
  • BOM浏览器对象模型
  • DOM
  • 事件
  • js对象数组sort按需排序
  • 文件上传功能技术选型和前后端实现
  • 前端图片处理
  • 让你的JavaScript代码简单又高效
  • BEM:class命名规范
  • 前端规范-CSS属性那么多(杂),怎么排序
  • TypeScript Tips
  • jsx
  • canvas基础
  • 前端日志
  • 浏览器存储
    • CSS世界阅读笔记
    • CSS揭秘阅读笔记
    • js变量命名常用规范词
    • 你不知道的JavaScript阅读笔记
    • js对象的底层数据结构
    • js判断数据类型
    • JS浮点数精度问题和解决办法
    • js作用域
    • js堆栈溢出和内存泄漏
    • 浏览器是如何渲染页面的
    • 疑难杂症和踩坑问题合集
    • 免费在线API收集
    • 原生JS实现Ajax请求
    • cookie、session、localStorage、sessionStorage的区别
    • Sass与Less
    • arrayBuffer、blob、file对象
    • TypeScript基础
    • 前端
    XingYun
    2022-02-23
    目录

    浏览器存储

    参考 JavaScript 高级程序设计 第四版

    # cookie

    HTTP cookie 通常也叫作 cookie,最初用于在客户端存储会话信息。这个规范要求服务器在响应 HTTP 请求时,通过发送 Set-Cookie HTTP 头部包含会话信息。例如,下面是包含这个头部的一个 HTTP 响应:

    
    HTTP/1.1 200 OK
    Content-type: text/html
    Set-Cookie: name=value
    Other-header: other-header-value
    
    
    1
    2
    3
    4
    5
    6

    这个 HTTP 响应会设置一个名为"name",值为"value"的 cookie。名和值在发送时都会经过 URL 编码。浏览器会存储这些会话信息,并在之后的每个请求中都会通过 HTTP 头部 cookie 再将它们发回服 务器,比如:

    
    
    GET /index.jsl HTTP/1.1
    Cookie: name=value
    Other-header: other-header-value
    
    
    1
    2
    3
    4
    5
    6

    这些发送回服务器的额外信息可用于唯一标识发送请求的客户端。

    # 限制

    cookie 是与特定域绑定的。设置 cookie 后,它会与请求一起发送到创建它的域。这个限制能保证 cookie 中存储的信息只对被认可的接收者开放,不被其他域访问。因为 cookie 存储在客户端机器上,所以为保证它不会被恶意利用,浏览器会施加限制。同时,cookie 也不会占用太多磁盘空间。

    通常,只要遵守以下大致的限制,就不会在任何浏览器中碰到问题:

    1. 不超过 300 个 cookie;
    2. 每个 cookie 不超过 4096 字节;
    3. 每个域不超过 20 个 cookie;
    4. 每个域不超过 81 920 字节。

    浏览器也会限制 cookie 的大小。大多数浏览器对 cookie 的限制是不超过 4096 字节,上下可以有一 个字节的误差。为跨浏览器兼容,最好保证 cookie 的大小不超过 4095 字节。这个大小限制适用于一个 域的所有 cookie,而不是单个 cookie。

    如果创建的 cookie 超过最大限制,则该 cookie 会被静默删除。

    # cookie 构成

    cookie 在浏览器中是由以下参数构成的。

    1. 名称:唯一标识 cookie 的名称。cookie 名不区分大小写,因此 myCookie 和 MyCookie 是同一个名称。不过,实践中最好将 cookie 名当成区分大小写来对待,因为一些服务器软件可能这样对待它们。cookie 名必须经过 URL 编码。
    2. 值:存储在 cookie 里的字符串值。这个值必须经过 URL 编码。
    3. 域:cookie 有效的域。发送到这个域的所有请求都会包含对应的 cookie。这个值可能包含子域(如 www.wrox.com),也可以不包含(如.wrox.com 表示对 wrox.com 的所有子域都有效)。如果不明确设置,则默认为设置 cookie 的域。
    4. 路径:请求 URL 中包含这个路径才会把 cookie 发送到服务器。例如,可以指定 cookie 只能由http://www.wrox.com/books/访问,因此访问 http://www.wrox.com/下的页面就不会发送 cookie,即使请求的是同一个域。
    5. 过期时间:表示何时删除 cookie 的时间戳(即什么时间之后就不发送到服务器了)。默认情况下,浏览器会话结束后会删除所有 cookie。不过,也可以设置删除 cookie 的时间。这个值是 GMT 格 式(Wdy, DD-Mon-YYYY HH:MM:SS GMT),用于指定删除 cookie 的具体时间。这样即使关闭 浏览器 cookie 也会保留在用户机器上。把过期时间设置为过去的时间会立即删除 cookie。
    6. 安全标志:设置之后,只在使用 SSL 安全连接的情况下才会把 cookie 发送到服务器。例如,请 求 https://www.wrox.com 会发送 cookie,而请求 http://www.wrox.com 则不会。

    这些参数在 Set-Cookie 头部中使用分号加空格隔开,比如:

    
    HTTP/1.1 200 OK
    Content-type: text/html
    Set-Cookie: name=value; expires=Mon, 22-Jan-07 07:10:24 GMT; domain=.wrox.com Other-header: other-header-value
    
    
    
    1
    2
    3
    4
    5
    6

    这个头部设置一个名为"name"的 cookie,这个 cookie 在 2007 年 1 月 22 日 7:10:24 过期,对 www.wrox.com 及其他 wrox.com 的子域(如 p2p.wrox.com)有安全标志 secure 是 cookie 中唯一的非名/值对,只需一个 secure 就可以了。比如:

    
    HTTP/1.1 200 OK 17 Content-type: text/html
    Set-Cookie: name=value; domain=.wrox.com; path=/; secure
    Other-header: other-header-value
    
    
    1
    2
    3
    4
    5

    要知道,域、路径、过期时间和 secure 标志用于告诉浏览器什么情况下应该在请求中包含 cookie。 这里创建的 cookie 对所有 wrox.com 的子域及该域中的所有页面有效(通过 path=/指定)。不过, 这个 cookie 只能在 SSL 连接上发送,因为设置了 secure 标志。这些参数并不会随请求发送给服务器,实际发送的只有 cookie 的名/值对。

    # JavaScript 中的 cookie

    BOM 的 document.cookie 返回包含页面中所有有效 cookie 的字符串(根据域、路径、过期时间和安全设置),以分号分隔,如下面的例子所示:

    name1=value1;name2=value2;name3=value3

    所有名和值都是 URL 编码的,因此必须使用 decodeURIComponent()解码。

    在设置值时,可以通过 document.cookie 属性设置新的 cookie 字符串。这个字符串在被解析后会 添加到原有 cookie 中。设置 document.cookie 不会覆盖之前存在的任何 cookie,除非设置了已有的 cookie。设置 cookie 的格式如下,与 Set-Cookie 头部的格式一样:

    name=value; expires=expiration_time; path=domain_path; domain=domain_name; secure

    在所有这些参数中,只有 cookie 的名称和值是必需的。

    例: document.cookie = "name=Nicholas";

    # 使用 cookie 的注意事项

    还有一种叫作 HTTP-only 的 cookie。HTTP-only 可以在浏览器设置,也可以在服务器设置,但只能 在服务器上读取,这是因为 JavaScript 无法取得这种 cookie 的值。

    因为所有 cookie 都会作为请求头部由浏览器发送给服务器,所以在 cookie 中保存大量信息可能会影 响特定域浏览器请求的性能。保存的 cookie 越大,请求完成的时间就越长。即使浏览器对 cookie 大小有 限制,最好还是尽可能只通过 cookie 保存必要信息,以避免性能问题。

    # sessionStorage

    sessionStorage 对象只存储会话数据,这意味着数据只会存储到浏览器关闭。这跟浏览器关闭时 会消失的会话 cookie 类似。存储在 sessionStorage 中的数据不受页面刷新影响,可以在浏览器崩溃 并重启后恢复。

    因为 sessionStorage 对象与服务器会话紧密相关,所以在运行本地文件时不能使用。存储在 sessionStorage 对象中的数据只能由最初存储数据的页面使用,在多页应用程序中的用处有限。
    因为 sessionStorage 对象是 Storage 的实例,所以可以通过使用 setItem()方法或直接给属 性赋值给它添加数据。下面是使用这两种方式的例子:

    // 使用方法存储数据
    sessionStorage.setItem('name', 'Nicholas')
    // 使用属性存储数据
    sessionStorage.book = 'Professional JavaScript'
    
    1
    2
    3
    4

    所有现代浏览器在实现存储写入时都使用了同步阻塞方式,因此数据会被立即提交到存储。具体 API 的实现可能不会立即把数据写入磁盘(而是使用某种不同的物理存储),但这个区别在 JavaScript 层 面是不可见的。通过 Web Storage 写入的任何数据都可以立即被读取。

    对存在于 sessionStorage 上的数据,可以使用 getItem()或直接访问属性名来取得。下面是使 用这两种方式的例子:

    注意 Storage 类型只能存储字符串, 非字符串数据在存储之前会自动转换为字符串。

    注意,这种转换不能在获取数据时撤销。

    // 使用方法取得数据
    let name = sessionStorage.getItem('name')
    // 使用属性取得数据
    let book = sessionStorage.book
    
    1
    2
    3
    4

    可以结合 sessionStorage 的 length 属性和 key()方法遍历所有的值:

    for (let i = 0, len = sessionStorage.length; i < len; i++){
      let key = sessionStorage.key(i);
      let value = sessionStorage.getItem(key);
      alert(`${key}=`${value}`);
    }
    
    1
    2
    3
    4
    5

    这里通过 key()先取得给定位置中的数据名称,然后使用该名称通过 getItem()取得值,可以依 次访问 sessionStorage 中的名/值对。
    也可以使用 for-in 循环迭代 sessionStorage 的值:

    for (let key in sessionStorage) {
      let value = sessionStorage.getItem(key)
      alert(`${key}=${value}`)
    }
    
    1
    2
    3
    4

    每次循环,key 都会被赋予 sessionStorage 中的一个名称;这里不会返回内置方法或 length 属性。

    要从 sessionStorage 中删除数据,可以使用 delete 操作符直接删除对象属性,也可以使用 removeItem()方法。下面是使用这两种方式的例子:

    // 使用 delete 删除值
    delete sessionStorage.name
    // 使用方法删除值
    sessionStorage.removeItem('book')
    
    1
    2
    3
    4

    sessionStorage 对象应该主要用于存储只在会话期间有效的小块数据。如果需要跨会话持久存储 数据,可以使用 localStorage。

    # localStorage对象

    localStorage 对象取代了 globalStorage,作为在客户端持久存储 数据的机制。要访问同一个 localStorage 对象,页面必须来自同一个域(子域不可以)、在相同的端 口上使用相同的协议。

    因为 localStorage 是 Storage 的实例,所以可以像使用 sessionStorage 一样使用 localStorage。比如下面这几个例子:

    
    // 使用方法存储数据 
    localStorage.setItem("name", "Nicholas"); 
    
    // 使用属性存储数据
    localStorage.book = "Professional JavaScript";
    
    // 使用方法取得数据
    let name = localStorage.getItem("name)
    
    // 使用属性取得数据
    let book = localStorage.book;
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    两种存储方法的区别在于,存储在 localStorage 中的数据会保留到通过 JavaScript 删除或者用户 清除浏览器缓存。localStorage 数据不受页面刷新影响,也不会因关闭窗口、标签页或重新启动浏览 器而丢失。

    不同浏览器给 localStorage 和 sessionStorage 设置了不同的空间限制,但大多数会限制为每 个源 5MB。

    # 总结

    总结一下三大方案各自的特点以及适用场景:

    Cookie

    能被服务器指定,浏览器会自动在请求中带上
    大小只有 4kb
    大规模应用于广告商定位用户
    配合 session 也是一个可行的登录鉴权方案

    Web Storage

    大小有 10MB,使用极其简单
    但是只能存字符串,需要转义才能存 JS 对象
    大部分情况下能完全替代 Cookie,且更安全
    配合 token 可以实现更安全的登录鉴权

    IndexedDB

    储存空间无上限,功能极其强大
    原生支持 JS 对象,能更好的储存数据
    以数据库的形式储存数据,数据管理更规范
    但是,原生 API 操作很繁琐,且有一定使用门槛

    #浏览器
    上次更新: 2023/04/05, 09:41:10
    前端日志
    CSS世界阅读笔记

    ← 前端日志 CSS世界阅读笔记→

    最近更新
    01
    JavaScript-test
    07-20
    02
    二维码的原理
    07-20
    03
    利用ChatGPT优化代码
    07-20
    更多文章>
    Theme by Vdoing | Copyright © 2021-2023 XingYun | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式