我在django的设置启用了
'django.middleware.common.CommonMiddleware',
`django.middleware.http.ConditionalGetMiddleware`,
中间件,并且设置了USE_ETAGS = True
。
页面响应时有返回Etag数据,但请求时没有携带If-None-Match
信息(图1,图2是静态文件的request和response信息),所以导致同一个页面每次刷新都是200状态码,而不是304。
图1:
图2:
问:我还需要做什么设置或操作才能让页面请求时携带If-None-Match或If-Modified-Since头信息。
因为题主的两张图不是请求的同一个资源,没有办法很明确的得知上下文准确信息。下面我会用同一个资源的两次请求来解释下这个问题。
明确一个概念:
第一次请求、应答报文如下:
可以看到,响应报文返回了 cache-control: public, max-age=0 就是说,该资源可以被客户端或者代理缓存,也就是说谁都可以缓存,谁都可以取用。并且,该资源的缓存有效期是 0 (意思是缓存立马失效)。
刷新页面后,来看第二次的请求、应答报文:
可以看到 请求报文中有条件请求头字段。if-Modified-Since 的值是第一次报文中 last-modified 的值; if-None-Match 的值是第一次报文中 etag 的值。
为什么会有条件请求字段呢。是因为缓存过期了(因为第一次响应报文中 max-age=0, 0就表示过期 ),所以浏览器会从缓存中查找是否有etag、last-modified字段(注意,缓存是缓存的整个报文,而不仅仅是body部分),有的话,就在请求中带上,向服务器发起协商缓存请求,由服务器决定本地的这个缓存资源是否可以使用。(因为有时候会存在一种情况是,虽然本地缓存过期了,但是服务器上该资源其实也是自从上一次更新后就没有生成更新的数据了)。
如果服务器发现资源没有改变,就返回304响应,浏览器就知道,本地缓存中的这个数据资源可以继续使用。(304响应是没有body体的,只有头字段等元信息)
也就是说,只有在缓存过期的情况下,请求报文中才会有条件请求的相关字段。什么情况下,缓存会过期呢?如下:
总结: 浏览器发起http请求时,总是会先查看缓存,然后决定是否发起,以及发起什么类型的http请求。
=================
补充回答: