浏览器存储

浏览器存储

随着Web应用程序的出现,直接在客户端存储用户信息的需求也随之出现。与特定用户相关的信息应该保存在用户的机器上。无论是登录信息,个人偏好,还是其他数据,Web应用程序都需要有办法把它们保存在客户端。

对于该问题的第一个解决方案就是使用到了cookie,cookie由网景公司发明,由一份名为Persistent Client State:HTTP Cookies的规范定义,今天,cooike只是在客户端的存储数据的一个选项。

一.cookie

1.cookie的来源

Cookie 的本职工作并非本地存储,而是“维持状态”。 因为HTTP协议是无状态的,HTTP协议自身不对请求和响应之间的通信状态进行保存,通俗来说,服务器不知道用户上一次做了什么,这严重阻碍了交互式Web应用程序的实现。在典型的网上购物场景中,用户浏览了几个页面,买了一盒饼干和两瓶饮料。最后结帐时,由于HTTP的无状态性,不通过额外的手段,服务器并不知道用户到底买了什么,于是就诞生了Cookie。它就是用来绕开HTTP的无状态性的“额外手段”之一。服务器可以设置或读取Cookies中包含信息,借此维护用户跟服务器会话中的状态。

我们可以把Cookie 理解为一个存储在浏览器里的一个小小的文本文件,它附着在 HTTP 请求上,在浏览器和服务器之间“飞来飞去”。它可以携带用户信息,当服务器检查 Cookie 的时候,便可以获取到客户端的状态。

在刚才的购物场景中,当用户选购了第一项商品,服务器在向用户发送网页的同时,还发送了一段Cookie,记录着那项商品的信息。当用户访问另一个页面,浏览器会把Cookie发送给服务器,于是服务器知道他之前选购了什么。用户继续选购饮料,服务器就在原来那段Cookie里追加新的商品信息。

结帐时,服务器读取发送来的Cookie就行了。

2.什么是cookie及应用场景

Cookie指某些网站为了辨别用户身份而储存在用户本地终端上的数据(通常经过加密)。 cookie是服务端生成,客户端进行维护和存储

通过cookie,可以让服务器知道请求是来源哪个客户端,就可以进行客户端状态的维护,比如登陆后刷新,请求头就会携带登陆时response header中的set-cookie,Web服务器接到请求时也能读出cookie的值,根据cookie值的内容就可以判断和恢复一些用户的信息状态。

在这里插入图片描述

Cookie 以键值对的形式存在

典型的应用场景有:

  • 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息);
  • 个性化设置(如用户自定义设置、主题等);
  • 浏览器行为跟踪(如跟踪分析用户行为等)。

3. Cookie的原理及生成方式

Cookie的原理
cooike的原理

第一次访问网站的时候,浏览器发出请求,服务器响应请求后,会在响应头里面添加一个Set-Cookie选项,将cookie放入到响应请求中,在浏览器第二次发请求的时候,会通过Cookie请求头部将Cookie信息发送给服务器,服务端会辨别用户身份,另外,Cookie的过期时间、域、路径、有效期、适用站点都可以根据需要来指定。

Cookie的生成方式主要有两种:

  • 生成方式一:http response header中的set-cookie

我们可以通过响应头里的 Set-Cookie 指定要存储的 Cookie 值。默认情况下,domain 被设置为设置 Cookie 页面的主机名,我们也可以手动设置 domain 的值。

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2018 07:28:00 GMT;
//可以指定一个特定的过期时间(Expires)或有效期(Max-Age)
  • 生成方式二:js中可以通过document.cookie可以读写cookie,以键值对的形式展示

例如我们在掘金社区控制台输入以下三句代码,便可以在Chrome 的 Application 面板查看生成的cookie:

document.cookie="userName=hello"
document.cookie="gender=male"
document.cookie='age=20;domain=.baidu.com'

在这里插入图片描述

从上图中我们可以得出:

Domain 标识指定了哪些域名可以接受Cookie。如果没有设置domain,就会自动绑定到执行语句的当前域。 如果设置为”.baidu.com”,则所有以”baidu.com”结尾的域名都可以访问该Cookie,所以在掘金社区上读取不到第三条代码存储Cookie值。

4. cookie的缺陷

  • cookie不够大

    cookie的限制(通常,只要遵守以下大致的规则,就不会再任何浏览器中碰到问题)

    • 不超过300个cookie
    • 每个cookie不超过4096字节( 4 k b )=>一个二进制位=1位,8位(bit)=1字节,1024字节=1 k b
    • 每个域不超过20个cookie;
    • 每个域不超过81920字节。

​ 每个域能设置的cookie总数也是受限的,但不同的浏览器的限制不同,例如:

​ 最新版IE和Edge限制每个域不超过50个cookie;

​ 最新版Firefox限制每个域不超过150个cookie;

​ 最新版Opera限制每个域不超过180个cookie;

​ Safari和Chrome对每个域的cookie数没有硬性限制

如果cookie总数超过了单个域的上限,浏览器就会删除之前设置的cookie.IE和Opera会按照最近最少使用原则删除之前的cookie,以便为新设置的cookie腾出空间。Firefox好像会随机删除之前的cookie,因此为避免不确定的结果,最好不要超出限制。

  • 过多的 Cookie 会带来巨大的性能浪费

Cookie 是紧跟域名的。同一个域名下的所有请求,都会携带 Cookie。大家试想,如果我们此刻仅仅是请求一张图片或者一个 CSS 文件,我们也要携带一个 Cookie 跑来跑去(关键是 Cookie 里存储的信息并不需要),这是一件多么劳民伤财的事情。Cookie 虽然小,请求却可以有很多,随着请求的叠加,这样的不必要的 Cookie 带来的开销将是无法想象的。

cookie是用来维护用户信息的,而域名(domain)下所有请求都会携带cookie,但对于静态文件的请求,携带cookie信息根本没有用,此时可以通过cdn(存储静态文件的)的域名和主站的域名分开来解决。

  • 由于在HTTP请求中的Cookie是明文传递的,所以安全性成问题,除非用HTTPS。

5. cookie与安全

对于 cookie 来说,我们还需要注意安全性。

在这里插入图片描述

HttpOnly 不支持读写,可以在浏览器设置,也可以在服务器设置,但是只能在服务器读取。因为浏览器不允许脚本操作document.cookie去更改cookie, 所以为避免跨域脚本 (XSS) 攻击,通过JavaScript的 Document.cookie API无法访问带有 HttpOnly 标记的Cookie,它们只应该发送给服务端。如果包含服务端 Session 信息的 Cookie 不想被客户端 JavaScript 脚本调用,那么就应该为其设置 HttpOnly 标记。

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly

标记为 Secure 的Cookie只应通过被HTTPS协议加密过的请求发送给服务端。但即便设置了 Secure 标记,敏感信息也不应该通过Cookie传输,因为Cookie有其固有的不安全性,Secure 标记也无法提供确实的安全保障。

为了弥补 Cookie 的局限性,让“专业的人做专业的事情”,Web Storage 出现了。

这样有了WebStorage后,

cookie能只做它应该做的事情了——作为客户端与服务器交互的通道,保持客户端状态。

二,WebStorage

两个目标:

  • 提供在cookie之外的存储会话数据的途径

  • 提供跨会话持久化存储大量数据的机制

两个对象

  • localStorage永久存储机制

  • sessionStorage跨会话的存储机制,浏览器关闭则数据消失, 需要注意的是 sessionStorage 的作用域是窗口级别的,也就是说不同窗口之间保存的 sessionStorage 数据是不能共享的。

三,localStorage

一种持久化的存储方式,也就是说如果不手动清除,数据就永远不会过期。它是采用键值对的方式存储数据,按域名将数据分别保存到对应数据库文件里。相比 Cookie 来说,它能保存更大的数据。

localStorage 的特点:

  • 大小限制为 5MB ~10MB;

  • 在同源的所有标签页和窗口之间共享数据;

  • 数据仅保存在客户端,不与服务器进行通信;

  • 数据持久存在且不会过期,重启浏览器后仍然存在;

  • 对数据的操作是同步的。

示例:

// 通过setItem()增加一个数据项
localStorage.setItem('myName', 'Semlinker');

// 通过getItem()获取某个数据项
let me = localStorage.getItem('myName');

// 通过removeItem()移除某个数据项
localStorage.removeItem('myName');

// 移除所有数据项
localStorage.clear();

四. sessionStorage

与服务端的 session 类似,sessionStorage 是一种会话级别的缓存,关闭浏览器时数据会被清除。需要注意的是 sessionStorage 的作用域是窗口级别的,也就是说不同窗口之间保存的 sessionStorage 数据是不能共享的。

sessionStorage 的特点:

  • sessionStorage 的数据只存在于当前浏览器的标签页;
  • 数据在页面刷新后依然存在,但在关闭浏览器标签页之后数据就会被清除;
  • 与 localStorage 拥有统一的 API 接口;
  • 对数据的操作是同步的。

「示例」

// 通过setItem()增加一个数据项
sessionStorage.setItem('myName', 'Semlinker');

// 通过getItem()获取某个数据项
let me = sessionStorage.getItem('myName');

// 通过removeItem()移除某个数据项
sessionStorage.removeItem('myName');

// 移除所有数据项
sessionStorage.clear();

五.Web SQL

Web SQL 数据库 API 实际上不是 HTML5 规范的一部分,而是一个单独的规范,它引入了一组 API 来使用 SQL 来操作客户端数据库。需要注意的是,HTML5 已经放弃 Web SQL 数据库。

六. IndexedDB

IndexedDB 是一种底层 API,用于客户端存储大量结构化数据,包括文件、二进制大型对象。该 API 使用索引来实现对该数据的高性能搜索。虽然 Web Storage 对于存储较少量的数据很有用,但对于存储更大量的结构化数据来说,这种方法不太好用。IndexedDB 提供了一个解决方案。

IndexedDB 的特点:

  • 存储空间大:存储空间可以达到几百兆甚至更多;

  • 支持二进制存储:它不仅可以存储字符串,而且还可以存储二进制数据;

  • IndexedDB 有同源限制,每一个数据库只能在自身域名下能访问,不能跨域名访问;

  • 支持事务型:IndexedDB 执行的操作会按照事务来分组的,在一个事务中,要么所有的操作都成功,要么所有的操作都失败;

  • 键值对存储:IndexedDB 内部采用对象仓库(object store)存放数据。所有类型的数据都可以直接存入,包括 JavaScript 对象。对象仓库中,数据以 “键值对” 的形式保存,每一个数据记录都有对应的主键,主键是独一无二的,不能有重复,否则会抛出一个错误。

  • 数据操作是异步的:使用 IndexedDB 执行的操作是异步执行的,以免阻塞应用程序。

「示例」

var dbName = "my_db";

var request = indexedDB.open(dbName, 2);

request.onerror = function(event) {
  // 错误处理
};

request.onupgradeneeded = function(event) {
  var db = event.target.result;

  // 建立一个对象仓库来存储我们客户的相关信息,我们选择 ssn 作为键路径(key path)
  // 因为 ssn 可以保证是不重复的
  var objectStore = db.createObjectStore("customers", { keyPath: "ssn" });

  // 建立一个索引来通过姓名来搜索客户。名字可能会重复,所以我们不能使用 unique 索引
  objectStore.createIndex("name", "name", { unique: false });

  // 使用邮箱建立索引,我们确保客户的邮箱不会重复,所以我们使用 unique 索引
  objectStore.createIndex("email", "email", { unique: true });

  // 使用事务的 oncomplete 事件确保在插入数据前对象仓库已经创建完毕
  objectStore.transaction.oncomplete = function(event) {
    // 将数据保存到新创建的对象仓库
    var customerObjectStore = db.transaction("customers", "readwrite").objectStore("customers");
    customerData.forEach(function(customer) {
      customerObjectStore.add(customer);
    });
  };
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值