http缓存机制

强缓存与协商缓存规则

缓存目的在于减少静态资源不必要的请求次数

核心区别在于:强缓存优先判断本地资源是否过期,无需向服务器发起请求;协商缓存则需先向服务器确认资源是否更新,再决定是否复用本地缓存

浏览器缓存

浏览器缓存按照存储位置分为内存缓存(memory cache)与硬盘缓存(disk cache)

按照缓存机制分强缓存 协商缓存

强缓存

对比在浏览器内部的缓存数据库是否包含请求所需的数据(缓存是否命中),未命中则请求数据

强缓存的策略很粗暴,只判断有无

返回状态码

200 OK (from cache) 或 200 OK (from memory cache)

强缓存判断缓存是否命中的机制(Expires字段,过期时间),通过将本地时间戳与Expires对比判断是否请求资源

强缓Cache-Control(HTTP/1.1新增,现代浏览器支持)字段的取值如下(可多值组合):

  • max-age:浏览器资源缓存的时长(秒),比Expires优先级高

  • no-cache:不走强缓存,**走协商缓存**

  • no-store:禁止任何缓存策略

  • public:资源即可以被浏览器缓存也可以被代理服务器缓存(CDN)

  • private:资源只能被客户端缓存

// 设置强缓存头
app.get('/api/data', (req, res) => {
  res.setHeader('Cache-Control', 'private, max-age=3600');
  res.setHeader('Expires', new Date(Date.now() + 3600000).toUTCString());
  res.send('Data from server');
});

协商缓存(对比缓存)

返回状状态码

  • 若资源未更新:服务器返回 304 Not Modified,客户端复用本地缓存。

  • 若资源已更新:服务器返回 200 OK 并携带新资源,客户端更新本地缓存。

1. Last-Modified(响应头) + If-Modified-Since(请求头)

Last-Modified 和 If-Modified-Since:服务器通过 Last-Modified 响应头告知客户端资源的最后修改时间。客户端在后续请求中通过 If-Modified-Since 请求头携带该时间,服务器判断资源是否有更新。如果没有更新,返回 304 状态码

2. ETag(响应头) + If-None-Match(请求头)

ETag 和 If-None-Match:服务器通过 ETag 响应头给资源生成一个**唯一标识符**。客户端在后续请求中通过 If-None-Match 请求头携带该标识符,服务器根据标识符判断资源是否有更新。如果没有更新,返回 304 状态码

ETag 优先级高Last-Modified

强缓存优先级更高

浏览器会先检查强缓存是否生效(未过期),如果生效则直接使用本地缓存,**完全不向服务器发送请求**,此时协商缓存根本没有参与的机会

app.use(express.static('public'), {
  maxAge: '1h',
  lastModified: true,
});

以上代码翻译为:使用强缓存策略缓存静态资源,1h后发请求才触发协商缓存(携带 If-Modified-Since 头),判断静态资源是否修改,是则请求新资源,否则继续使用缓存

app.use(express.static('public'), { maxAge: '1h' })

过期后无论文件是否修改都直接请求资源

app.use(express.static('public'), { lastModified: true })

每次请求都携带If-Modified-Since 头)判断是否需要更新静态资源

http常见状态码

状态码分为五类

分类

分类描述

1**

信息,服务器收到请求,需要请求者继续执行操作

2**

成功,操作被成功接收并处理

3**

重定向,需要进一步的操作以完成请求

4**

客户端错误,请求包含语法错误或无法完成请求

5**

服务器错误,服务器在处理请求的过程中发生了错误

常见的状态码

  1. 200 OK:一切正常

  2. 301 Moved Permanently:资源已被永久重定向
       请求收到了,但资源不在这个地址了,后端已经永远的把它移动到了一个新的地址,需要请求新的地址,地址放到了响应头的Location中

  3. 302 Found:资源已被临时重定向
       请求收到了,但资源不在这个地址了,后端临时的把它移动到了一个新的地址,需要请求新的地址,地址放到了请求头的Location中了

  4. 304 Not Modified:文档内容未被修改,浏览器走了协商缓存
       请求收到了,请求资源没有任何的变化,可以使用缓存以前的内容

  5. 400 Bad Request:语义有误,当前请求无法被服务器理解
       请求格式有误

  6. 403 Forbidden:服务器拒绝执行
       请求收到,但是没有权限

  7. 404 Not Found:资源不存在
       请求收到,资源不存在

  8. 500 Internal Server Error:服务器内部错误
       服务器虽接收到请求,但无法处理

  9. 502 Bad Gateway:当前服务器作为代理/网关,从上游服务器收到无效响应
       请求收到,nginx之类的代理服务器请求上游服务器响应无效

http常用方法

6个最常用方法

方法

核心作用

安全性

幂等性

数据传递方式

典型场景

GET

获取资源

URL 拼接

查列表、查详情、加载静态资源

POST

提交 / 创建资源

请求体

表单提交、创建用户、上传文件

PUT

全量更新资源

请求体(完整字段)

全量修改用户信息

DELETE

删除资源

URL 标识(可选请求体)

删除用户、删除订单

PATCH

部分更新资源

请求体(部分字段)

修改用户手机号、文章状态

HEAD

仅获取响应头

URL 拼接

检查资源存在、获取元信息

Get 与 Post 的区别

从 http 协议的角度来说,GET 和 POST 它们都只是请求行中的第一个单词,除了语义不同,其实没有本质的区别。

之所以在实际开发中会产生各种区别,主要是因为浏览器的默认行为造成的。

受浏览器的影响,在实际开发中,GET 和 POST 有以下区别:

  1. 浏览器在发送 GET 请求时,不会附带请求体(但协议未禁止)

  1. GET 请求的传递信息量有限,适合传递少量数据,浏览器对URL长度有限制;POST 请求的传递信息量是没有限制的,适合传输大量数据,但实际上服务端会有限制(Nginx默认只允许1MB)。

  1. GET 请求只能传递 ASCII 数据,遇到非 ASCII 数据需要进行编码;POST 请求没有限制

  1. 安全性上,大部分 GET 请求传递的数据都附带在 path 参数中,能够通过分享地址完整的重现页面,但同时也暴露了数据,若有敏感数据传递,不应该使用 GET 请求,至少不应该放到 path 中

  1. 刷新页面时,若当前的页面是通过 POST 请求得到的,则浏览器会提示用户是否重新提交。若是 GET 请求得到的页面则没有提示。(幂等性)

  1. GET 请求的地址可以被保存为浏览器书签,POST 不可以(幂等性)

  1. GET是幂等的,POST是非幂等的,只有POST会改变服务器状态

  1. GET更容易被浏览器或CDN缓存