HTTP系列 -- Session + Storage + Cache-Control + ETag + Cookie

概述

本文主要讲述 Session + Storage + Cache-Control + ETag + Cookie 这五者的作用及区别

Session

首先通过代码认识一下 Session。之前我们说 Cookie 可以存储我们的一些信息,但是由于用户在浏览器中可以对 Cookie 进行操作,显然这不是我们想要的,所以 Session 应运而生,Session 解决了 Cookie 不安全的痛点

code

我们在内存中开辟一个空间,用来存储 Session

let sessions = {}

当用户登录成功时

let sessionId = Math.random() * 1000000
sessions[ sessionId ] = { key: value }  // 表示存储的用户信息
response.setHeader( 'Set-Cookie', `sessionId = ${ sessionId }` )  // Cookie: 'sessionId = 随机数'

当此用户访问首页时,遍历 Cookie,将所有 Cookie 存储到一个 hash(哈希表)中,之后

let mySession = sessions[ hash.sessionId ]
let username
if( mySession ){
    username = mySession.用户信息  // 用户信息表示 sessions 中的{ key: value }
}
Session 特点
  1. 服务器通过 Cookie(sessionId = ${ sessionId }) 将 SessionId(随机数)发给浏览器
  2. 服务器有一块内存保存了所有的 Session(哈希表)
  3. 当浏览器访问服务器时,服务器读取 SessionId
  4. 服务器通过 SessionId 可以得到对应用户的隐私信息
  5. 用户每次登录都会设置一个 SessionId,并且 SessionId 不保存在服务器中

Storage

作为 Web Storage API 的接口(HTML5),Storage 提供了访问特定域名下的会话存储(session storage)和本地存储(local storage)的功能,例如:增删改查存储的数据项。Storage 与 HTTP 无关,它是浏览器上的哈希表,Storage 文件存储在本地的一个文件夹中

  • window.sessionStorage ==> 操作一个域名的会话存储(session storage)
  • window.localStorage ==> 操作一个域名的本地存储(local storage)

API

  • Storage.setItem() ==> 接收一个键名和值作为参数,把键值对添加到存储中,如果键名存在,则更新其对应的值

  • Storage.getItem() ==> 接收一个键名作为参数,返回键名对应的值

  • Storage.removeItem() ==> 接收一个键名作为参数,并把该键名从存储中删除

  • Storage.clear() ==> 清空存储中的所有键名

对象的存储
localStorage.setItem( 'object', { name: 'obj' } )  // object  [ object Object ]

存储对象

浏览器会将 { name: 'obj' } 转化为字符串即 ({ name: 'obj' }).toString,所以当我们存储对象时,使用 JSON ,即

localStorage.setItem( 'object', JSON.stringify({ name: 'obj' }))

localStorage

使用场景

记录是否提示过用户 + 记录一些不敏感的信息,常见新手引导界面

let already = localStorage.getItem( 'isGuide' )
if( !already ){
    // 开启引导
    localStorage.setItem( 'isGuide', true )
}
特点
  1. localStorage 与 HTTP 无关,所以 HTTP 不会带上 localStorage 的值
  2. 每个域名的 localStorage 有最大存储量,因浏览器而异
  3. 只有相同域名的页面才能互相读取 localStorage
  4. localStorage 永久有效,除非用户清除

sessionStorage

特点
  1. sessionStorage 与 HTTP 无关,所以 HTTP 不会带上 sessionStorage 的值
  2. 每个域名的 sessionStorage 有最大存储量,因浏览器而异
  3. SessionStorage 只在同一浏览器窗口中共享
  4. sessionStorage 在用户关闭页面后就会失效

Cache-Control

Cache-Control 通用消息头被用于在 HTTP 请求和响应中通过指定指令来实现缓存机制。当我们请求的文件(css、js)很大时,可以使用 Cache-Control 实现缓存,从而达到性能优化的目的
前提:使用相同的 URL 才能实现 Cache-Control 缓存机制

HTML
<link rel = "stylesheet" href = "URL">
<script src = "URL">

后端 + code

else if( path === '/js/main.js' ){
    response.setHeader( 'Cache-Control', 'max-age = 30' )  
    // 30s 内如果请求 main.js 文件,浏览器不发送请求,直接使用缓存中文件 ==> 下载时间 === 0
}

特点

  1. 让浏览器在一段时间内不访问服务器,不发送请求,直接使用本地硬盘 | 内存作为响应,从而减少请求时间
  2. 首页(入口文件 + HTML)不设置 Cache-Control,因为在缓存的这段时间内,用户不能获取最新网页
  3. 其他文件(css + js)会缓存很久(10年,甚至更久),如要更新,只需要改变入口文件(HTML)的 URL 即可,之后浏览器就会缓存最新版的文件
  4. URL 改变实现方式:+ 查询参数 | + 随机数


    URL 改变实现 + 随机数

Expires

Expires 头指定了一个日期 | 时间, 在这个日期 | 时间之后,HTTP响应被认为是过时的

Cache-Control | Expires

从 Expires ==> Cache-Control 是 HTTP 升级的过程,以前使用 Expires 加缓存,现在使用 Cache-Control 加缓存,Expires 的问题在于,它的过期时间是本地的时间,如果本地时间错乱,可能导致用户一直不能使用缓存,从而影响用户体验
两者的区别在于:Cache-Control 设置缓存时长,Expires 设置缓存过期时间点。如果两者同时设置,Cache-Control 优先使用

ETag

ETag HTTP 响应头是资源的特定版本的标识符。可以让缓存更加高效并节省宽带,如果内容没有改变,Web 服务器不需要发送完整的响应

MD5

MD5 指摘要算法,它可以把一个文件转化成一个字符串。若文件内容相同,则字符串相同。文件内容差异越小,字符串(算出来的结果)差异越大

后端 + code

安装 MD5 npm install md5,然后 node.js 使用 MD5

else if( path === '/js/main.js' ){
    let string = fs.readFileSync( './js/main.js', 'utf-8' )
    let fileMd5 = md5( string )
    response.setHeader( 'ETag', fileMd5 )  // 响应头中有 ETag ==> ETag: md5 值
    // 当设置了 ETag 响应头,下次刷新时,请求中会多一个 If-None-Match 的请求头,值为 ETag 的值(md5 值)
    if( request.header[ 'if-none-match' ] === fileMd5 ){  // 如果请求的版本号(md5 值) === 浏览器的 If-None-Match 的值(md5 值) ==> 相同版本不需要下载
        // 没有响应体
        response.statusCode = 304  
        // 304 Not Modified 表示资源未被修改,因为请求头指定的版本If-Modified-Since或If-None-Match。在这种情况下,由于客户端仍然具有以前下载的副本,因此不需要重新传输资源。
    } else{
        response.statusCode = 200
        // 有响应体
        response.write( string )
    }
    response.end()
}

缓存机制

Cache-Control + ETag 联合使用

辨析

Cookie + Session

  1. Cookie 指某些服务器在浏览器终端的一些数据(通常经过加密),一般为了辨别用户身份,也可以储存少量信息
  2. Session 是指服务器通过某种方式确定了用户身份后的会话状态,一般表现为服务器为每个用户单独存储的一部分数据
  3. Session 是基于 Cookie 实现的,Cookie 是 Session 的基石
  4. Cookie 存储在浏览器本地,用户可以看到内容。Session 存储在服务器,用户无法查看内容,一般 Session 的内容是进程\线程间共享的
  5. Cookie 不安全,而 Session 解决了 Cookie 不安全的痛点

Cookie + Storage

  1. Cookie 和 Storage 都存储在本地的一个文件中
  2. 两者都可以做跨页面通信,两者都不能跨域访问
  3. Cookie 的每次请求相同域名时,都会带上 Cookie 里的所有内容去访问服务器
  4. Storage 与 HTTP 无关,不会被带给服务器
  5. Cookie 在做跨页面通信时,由于带上所有内容,导致上传数据 + 请求变慢,Storage 的出现解决了 Cookie 的痛点,只要将一些不敏感信息存储在 Storage 中即可
  6. JS 调用 Cookie 比较麻烦,一般都用库进行封装。Storage 调用起来比较简单,也可以再次封装达到更好的效果
  7. Cookie 大小 4K 左右,Storage 大小 5M 左右
  8. 后台代码可以任意设置 Cookie 的过期时间。Storage 中的 LocalStorage 永久有效,除非用户删除,Storage 中的 SessionStorage 在用户关闭页面(Session 结束)后就失效

LocalStorage + SessionStorage

  1. 两者与 HTTP 无关
  2. 每个域名的 LocalStorage | sessionStorage 有最大存储量,因浏览器而异
  3. 只有相同域名的页面才能互相读取 LocalStorage。SessionStorage 只在同一浏览器窗口中共享
  4. LocalStorage 本地存储, SessionStorage 会话存储
  5. LocalStorage 永久有效,除非用户删除。SessionStorage 在用户关闭页面(Session 结束)后就失效

Cache-Control + ETag

  1. 两者都是 HTTP 响应头,都可以实现加快请求 | 响应速度
  2. Cache-Control 是直接使用本地缓存,不会发送请求
  3. ETag 发送请求,如果 MD5 值相同,则没有响应体
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 1. cookie 1.1 什么是cookie cookie 是存储于访问者的计算机中的变量。每当同一台计算机通过...
    cbw100阅读 4,047评论 0 13
  • 本文介绍本地数据存储的选型。简单总结一些查询到的关于本地数据存储的技术。 控制台展示前端存储 Chrome: 前端...
    谢大见阅读 9,038评论 1 8
  • http协议有http0.9,http1.0,http1.1和http2三个版本,但是现在浏览器使用的是htt...
    一现_阅读 1,855评论 0 3
  • 本文是我今年2月份发表在博客园上的文章,平常做项目时便温故一下。私以为,只有通过实践才能将知识真正地内化和吸收,再...
    一个笑点低的妹纸阅读 827评论 0 2
  • 我原本想慢水煮鸡蛋,结果炒了。炒完后觉得太淡,就加了点酱油。又尝了尝,觉得太咸,只能加点热水冲下。最后我吃到了一碗...
    穆林月阅读 191评论 1 0