0


HTTP请求返回304状态码以及研究nginx中的304

文章目录

在这里插入图片描述

1. 引出问题

之前在调试接口时,代码总出现

304

问题,如下所示:

在这里插入图片描述

2. 分析问题

HTTP 304: Not Modified

是什么意思?

标准解释是:

Not Modified

客户端有缓冲的文档并发出了一个条件性的请求(一般是提供

If-Modified-Since

头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。

在这里插入图片描述

在请求头里有:If-Modified-Since:

Thu, 09 Feb 2023 14:36:34 GMT

在响应头里有:Last-Modified:

Thu, 09 Feb 2023 14:36:34 GMT

大家对比一下这二个日期发日期和时分秒都是完全一致的,如果一致就从缓存中去获取内容。

我们在图片中看到了一个它的

cache-control 

。

如果

cache-control:no-chache

,说明强制每次请求直接发送给源服务器,而不经过本地缓存版本的校验。

如果

cache-control:max-age=0

有二种情况:

  1. max-age>0时 直接从游览器缓存中提取
  2. max-age<=0时 向server发送http请求确认,该资源是否有修改?- 有,则返回200 - 无,则返回304。

第一次访问,返回

200

。

在这里插入图片描述

鼠标点击二次访问

(Cache)

。

在这里插入图片描述

3. 解决问题

按

F5

刷新,还是

304 

,无法解决该问题。

在这里插入图片描述

但按

Ctrl+F5

强制刷新,则返回

200

,可以解决这个问题。

在这里插入图片描述

一般情况下,出现这个问题,我们按

Ctrl+F5

强制刷新即可。

4. 研究nginx中的304

4.1 启动服务

在研究

nginx

日志时,对于

304

这个状态码产生了好奇。之前一直知道

3XX

系列的状态码表示重定向,但对于

304

的具体原理没有仔细研究过。

**

304

的标准解释是:客户端有缓冲的文档并发出了一个条件性的请求。服务器告诉客户端,原来缓冲的文档还可以继续使用。**

完成这个几个动作包括服务器确认返回

304

给予客户端,主要包含几个

http头信息,请求头If-None-Match、响应头ETag和响应头Cache-Control

。

为了更好的理解

304

状态码以及缓存,直接实验一把:

为了方便就使用

express

启动一个服务了

(express几行代码就搞定了)

。

var express =require('express');var app =express();
 
app.get('/',function(req, res){
  res.send('hello world');});
app.listen('8080')

启动之后,浏览器访问

localhost:8080

并观察请求,响应头。

第一次请求:

在这里插入图片描述

第二次请求:

在这里插入图片描述

第二次请求服务器返回了一个

304

。

在第一次请求服务器的时候在获取资源之后是会先把该资源缓存在本地的,同时服务器

response

返回了一个响应头

ETag

。

4.2 ETag说明

ETag全称Entity Tag

,用来标识一个资源。在具体的实现中,

ETag

可以是资源的

hash

值,也可以是一个内部维护的版本号。

但不管怎样,

ETag

应该能反映出资源内容的变化,这是

Http

缓存可以正常工作的基础。

服务器对于

hello world

这个字符串使用上述返回的

ETag

来表示,只要

hello world

这个资源不变,这个

Etag

就不会变。

客户端第二次请求服务器的时候,利用请求头

If-None-Match

来告诉服务器自己已经有个

ETag为xxx

的资源。

如果服务器上的资源没有变化,也就是说服务器上的资源的

ETag也是xxx

的话,服务器就不会再返回该资源的内容,而是返回一个

304

的响应,告诉浏览器该资源没有变化,缓存有效,浏览器将直接调用本地缓存。

4.3 响应头Cache-Control

每个资源都可以通过

Http

头

Cache-Control

来定义自己的缓存策略,

Cache-Control

控制谁在什么条件下可以缓存响应以及可以缓存多久。

最快的请求是不必与服务器进行通信的请求:通过响应的本地副本,我们可以避免所有的网络延迟以及数据传输的数据成本。

为此,

HTTP 

规范允许服务器返回一系列不同的

Cache-Control

指令,控制浏览器或者其他中继缓存如何缓存某个响应以及缓存多长时间。

Cache-Control 头在 HTTP/1.1

规范中定义,取代了之前用来定义响应缓存策略的头(例如

Expires

)。当前的所有浏览器都支持

Cache-Control

,因此,使用它就够了。

以下我来介绍可以再

Cache-Control

中设置的常用指令。

  1. max-age 

该指令指定从当前请求开始,允许获取的响应被重用的最长时间(单位为秒)。例如:

Cache-Control:max-age=60

表示响应可以再缓存和重用

60

秒。

需要注意的是,在

max-age

指定的时间之内,浏览器不会向服务器发送任何请求,包括验证缓存是否有效的请求,也就是说,如果在这段时间之内,服务器上的资源发生了变化,那么浏览器将不能得到通知,而使用老版本的资源。

所以在设置缓存时间的长度时,需要慎重。

  1. public和private

如果设置了

public

,表示该响应可以再浏览器或者任何中继的

Web

代理中缓存。

public是默认值,即Cache-Control:max-age=60等同于Cache-Control:public, max-age=60。

在服务器设置了

private

比如

Cache-Control:private, max-age=60

的情况下,表示只有用户的浏览器可以缓存private响应,不允许任何中继Web代理对其进行缓存 - 例如,用户浏览器可以缓存包含用户私人信息的

HTML

网页,但是

CDN 

不能缓存。

  1. no-cache

如果服务器在响应中设置了

no-cache

即

Cache-Control:no-cache

,那么浏览器在使用缓存的资源之前,必须先与服务器确认返回的响应是否被更改,如果资源未被更改,可以避免下载。

这个验证之前的响应是否被修改,就是通过上面介绍的请求头

If-None-match

和响应头

ETag

来实现的。

需要注意的是,

no-cache

这个名字有一点误导。设置了

no-cache

之后,并不是说浏览器就不再缓存数据,只是浏览器在使用缓存数据时,需要先确认一下数据是否还跟服务器保持一致。

如果设置了

no-cache

,而

ETag

的实现没有反应出资源的变化,那就会导致浏览器的缓存数据一直得不到更新的情况。

  1. no-store

如果服务器在响应中设置了

no-store

即

Cache-Control:no-store

,那么浏览器和任何中继的

Web

代理,都不会存储这次相应的数据。当下次请求该资源时,浏览器只能重新请求服务器,重新从服务器读取资源。

标签: nginx http 服务器

本文转载自: https://blog.csdn.net/lvoelife/article/details/128965069
版权归原作者 super先生 所有, 如有侵权,请联系我们删除。

“HTTP请求返回304状态码以及研究nginx中的304”的评论:

还没有评论