Cookie
- server 通过 Set-Cookie 响应头设置 cookie
- browser的到 cookie 之后, 每次请求都会带上 cookie
- server 读取cookie 就知道登录用户的信息
问题
- 我在 chrome 登录了得到了 cookie, 用 safari 访问相同的地址, safari 不会带上cookie, 浏览器只负责管理自己的 cookie
- Cookie 存在哪里
- Windows 存在 C 盘下的一个文件
- 其他系统存在某个文件中
- cookie 能作假么? 可以
- cookie 不安全, 用户稍微有点前端知识可以随时更改
- cookie 有有效期么? 有
- 默认有效期 20min 左右( 浏览器会自行决定 cookie 的保留时间)
- 后端可以强制设置有效期
- cookie 是按域名分组的, 一个域名只能看到属于自己分组的 cookie
- HttpOnly 选fa项, 可以阻止JS更改 cookie
但用户仍可以手动更改document.cookie
在 nodejs 中读取 cookie, 有多个 cookie 时, 会用分号区分
request.headers.cookie
// cookie_name=value;cookie_name=value
Session:
- 将 SessionID( 随机数)通过 cookie 返回给客户端
- 客户端访问服务器时, 服务器读取 SessionID
- 服务器有一块内存( Hash Table) 保存了所有 session
- 通过 SessionID 我们可以得到对应用户的隐私信息, 如 id, email
- 这块内存就是服务其上所有的 session
LocalStorage
HTML5提供的一个新的 api, 其实质是一个 hash. Session 是服务器上的hash, LocalStorage 是浏览器上的 hash
-
主要用到三种方法, 他会直接将数据转换为字符串进行存储
setItem() getItem() removeItem()
-
特点
- LocalStorage 跟 HTTP 无关
- HTTP 不会带上 LocalStorage 的值
- 只要相同域名的页面才能相互读取 LocalStorage (没有同源那么严格)
- 每个域名 LocalStorage 的容量是有限的(每个浏览器不一样)
- LocalStorage 永久有效, 除非用户主动清除
-
常用场景
- 记录没有有提示过用户(没有用的信息, 非敏感信息
SessionStorage
- 其特点与 localStorage 相同, 除了在用户关闭页面后会失效
不基于 cookie 的 session 实现
后端产生的 sessionid, 可以不写在 cookie 中, 而是直接将 sessionid 的信息传递给客户端, 而后浏览器将 sessionid 存储在 localStorage 中, 每次访问时从 localstorage 中读取 session
Cache-control
对于比较耗时的资源访问过程, 在第一次访问时, 服务端可以设置 cache-control 响应头, 设置 max-age = 1000, 意思是告诉浏览器该文件让浏览器缓存1000s, 在1000内, 浏览器再次向相同的 url 请求该资源时, 浏览器会自动阻断请求, 转而使用内存中缓存的文件, 会显著提高加载速度. 等1000s 过去后, 才会再次向服务端请求资源.
-
问题: 为何首页不设置 cache-control
- 假设首页设置了1天的缓存, 那么用户此时间内(刷新, 回车), 将无法获得最新的页面内容
- html 尽量不要设置缓存
有一个合理的做法是, 将客户端邀请求的资源, 比如 css,js 等, 将其缓存尽量设置的之间长一些, 每当 css, js 出现新版本的时候, 可以去更改 html 中资源访问的 url 地址(在当前地址后更新版本号?v=xxxx/或者在资源名称中加入 md5值), 浏览器接收到 html 后, 仍会去访问相同的资源, 但由于 url 地址变更, 其不会在使用缓存中的资源, 而是获取服务器上的新资源
Expires
与Cache-Control功能一样,不同点是Cache-Control是设置多长时间后过期。Expires是直接设置一个过期的日期,格式为GMT
ETag
通过 ETag 验证缓存的响应
- 服务器使用 ETag HTTP 标头传递验证令牌
- 验证令牌可实现高效的资源更新检查:资源未发生变化时不会传送任何数据
假定在首次获取资源 120 秒后,浏览器又对该资源发起了新的请求。首先,浏览器会检查本地缓存并找到之前的响应。遗憾的是,该响应现已过期,浏览器无法使用。此时,浏览器可以直接发出新的请求并获取新的完整响应。不过,这样做效率较低,因为如果资源未发生变化,那么下载与缓存中已有的完全相同的信息就毫无道理可言!
在上例中,客户端自动在“If-None-Match” HTTP 请求标头内提供 ETag 令牌。服务器根据当前资源核对令牌。如果它未发生变化,服务器将返回“304 Not Modified”响应,告知浏览器缓存中的响应未发生变化,可以再延用 120 秒。请注意,您不必再次下载响应,这节约了时间和带宽。
这正是验证令牌(在 ETag 标头中指定)旨在解决的问题。服务器生成并返回的随机令牌通常是文件内容的哈希值或某个其他指纹。客户端不需要了解指纹是如何生成的,只需在下一次请求时将其发送至服务器。如果指纹仍然相同,则表示资源未发生变化,您就可以跳过下载。
Cache-control, Expires, ETag区别
Cache-Control, Expires是通过设置时间让浏览器阻断请求,ETag是没有阻断请求,是后端验证MD5是否改变来做出相应的响应