深入HTTP-缓存

缓存头Cache-Control

通过网络获取内容既缓慢,成本又高:大的响应需要在客户端和服务器之间进行多次往返通信,这拖延了浏览器可以使用和处理内容的时间,同时也增加了访问者的数据成本。因此,引入缓存解决避免重复获取某一内容的操作。
Cache-Control是通用首部字段,这意味着它能在请求报文和响应报文中使用。

Cache-Control格式

"Cache-Control" ":" cache-directive//可选值
作为请求头部时,cache-directive的可选值有:
字段名称说明
no-cache告知(代理)服务器不直接使用缓存,要求向原服务器发起请求
no-store所有内容都不会被保存到缓存或Internet临时条件中
max-age=seconds告知服务器,客户端希望接收一个存在时间不大于secodes秒的资源
no-transform告知(代理)服务器,客户端希望获取实体数据没有被压缩过

no-cache和no-store区别:no-cache从字面意义很容易被误解为不缓存,但是no-cache代表不缓存过期资源,缓存会向服务器进行有效处理确认之后处理资源,使用no-cache的目的就是为了防止从缓存中获取过期资源;而no-store才是真正的不进行缓存

作为响应头部时,cache-directive的可选值有:
字段名称说明
public表明任何情况下都得缓存该资源
private[=“field-name”]表明返回报文中全部或部分(若指定了field-name,则返回该指定的部分)给某些用户(服务器指定的用户),其他用户不能缓存这些数据
no-cache不直接使用缓存,要求向服务器发起请求
max-age=secodes告知客户端该资源在secodes秒内是新鲜的,无需向服务器端申请
…其他和请求头部中directive相同

在响应头部中设置缓存

const http = require('http')
const fs = require('fs')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  if (request.url === '/') {
    const html = fs.readFileSync('test.html', 'utf8')
    response.writeHead(200, {
      'Content-Type': 'text/html'
    })
    response.end(html)
  }

  if (request.url === '/script.js') {
    response.writeHead(200, {
      'Content-Type': 'text/javascript',
      'Cache-Control': 'max-age=20' //设置缓存新鲜度时间
    })
    response.end('console.log("script loaded")')
  }
}).listen(8888)

console.log('server listening on 8888')

在这里插入图片描述


资源验证
浏览器请求流程

在这里插入图片描述

验证头

本地缓存资源可以有效节省数据传输带来的开销,但是也存在一个问题:当服务器端修改了某资源,而客户端仍然从缓存从读取此资源,这样就导致读取的资源不是最新的,因此引入验证头来解决这一问题。

Last-Modified

在浏览器第一次请求某个URL时,服务器端的返回状态会是200,内容是你请求的资源,同时在响应头部会有一个Last-Modified的属性,该属性标记此文件在服务器端最后被修改的时间,格式类似这样:
Last-Modified: Fri, 12 May 2018 18:53:33 GMT
客户端第二次请求此URL时,浏览器会向服务器端传送If-Modified-Since报头,询问该时间之后文件是否有被修改过:
If-Modified-Since: Fri, 12 May 2018 18:53:33 GMT
如果服务器端的资源没有变化,则自动返回HTTP 304状态码,表示可以从本地缓存读取资源,这样就节省了传输数据量。当服务器端代码发生改变或者重启服务器,则重新发出资源,返回和第一次请求类似.从而保证不向客户端发送重复的资源,也保证当服务器对资源进行修改后,客户端能够得到最新的资源

Etag

Etag是一段数字签名,根据HTTP协议规格定位Etag为“被请求变量的实体值”。Etag的用法和Last-Modified相同。
以下是服务器端返回的格式:
ETag: “50b1c1d4f775c61:df3”
客户端的查询更新格式是这样的:
If-None-Match: W/"50b1c1d4f775c61:df3,如果ETag没改变,则返回状态304然后不返回。


Cookie&Session

由于HTTP协议是无状态协议,所以服务器端需要记录用户的状态时,就需要用某种机制来识别具体的用户。
在这里插入图片描述

Cookie

简单地说,Cookie就是浏览器存储在用户电脑上的一小段文本文件,Cookie是纯文本格式,不包括任何可执行代码。一个Web服务器告知浏览器存储这些信息,并在随后的请求中将这些信息发送至服务器,Web服务器可以使用这些信息来识别不同的用户。大多数登录的网站在用户验证成功之后都会设置一个Cookie,存储账号密码等信息,方便用户下次登录,“给用户点甜头”,这也是为什么就叫“Cookie”的由来。

  • 没有Cookie信息状态下的请求在这里插入图片描述
  • 第2次以后(存有Cookie信息状态)的请求在这里插入图片描述
设置Cookie

在响应头部中设置Cookie,由服务器告知浏览器去存储Cookie信息,之后的客户端请求中就会携带Cookie信息。

const http = require('http')
const fs = require('fs')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  if (request.url === '/') {
    const html = fs.readFileSync('test.html', 'utf8')
    response.writeHead(200, {
      'Content-Type': 'text/html',
      'Set-Cookie': ['id=123; max-age=2', 'abc=456;domain=test.com']//在响应头部设置Cookie
    })
    response.end(html)
  }

}).listen(8888)

console.log('server listening on 8888')

在这里插入图片描述

Session

Session对象存储特定用户会话所需的属性及配置信息,这样用户在Web页之间跳转时,存储在Session对象中的变量不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自Web页时,如果该用户还没有会话,则Web服务器将自动创建一个Session对象。服务端为特定的用户创建特定的Session来标识用户,并且跟踪用户。

通过Cookie管理Session
  1. 客户端把用户ID和密码等登录信息放入请求报文的正文部分,通常说以POST方法把请求发送到服务器上
  2. 服务器会发放用以识别用户的Session ID,通过验证从客户端发送来的登录信息进行身份认证,然后把用户的认证状态和Session ID绑定后记录在服务器端;最后向客户端返回响应时,会在响应报文头部中的首部字段Set-Cookie内写入Session ID
  3. 客户端接收到从服务器端发送来的Session ID,会将其作为Cookie保存在本地,下次向服务器请求时,浏览器会自动发送Cookie,所以Session ID也随之发送到服务器,服务器获取Session ID识别用户

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值