最近在跟后台对接口时,发现请求同一个接口时老是一次成功一次失败这样间隔着来,非常困扰。请求失败的时候报的错时
502 Not Modified
,这个报错也是百思不得解。在我掌握的知识里502
时服务器错误,而Not Modified
对应的状态码应该时304,但这样的报错提示是历来没有遇到过。另外这个错误也只是在本地跑的时候会有,放到线上的环境就很正常,第二次请求时也是304而不会报错。得闲我比较了本地两次调接口时的请求头,发现第二次也就是请求失败的时候请求头多了一个字段If-None-Match
,而后禁用了缓存,果真就不会有报错了,因此我猜测多是后台没有对缓存作处理吧。而后我去查阅资料学习了下请求头ETag
和If-Not-Match
.算法
它的原理是这样的,当浏览器请求服务器的某项资源(A)时, 服务器根据A算出一个哈希值(3f80f-1b6-3e1cb03b)并经过 ETag 返回给浏览器,浏览器把"3f80f-1b6-3e1cb03b" 和 A 同时缓存在本地,当下次再次向服务器请求A时,会经过相似 If-None-Match: "3f80f-1b6-3e1cb03b" 的请求头把ETag发送给服务器,服务器再次计算A的哈希值并和浏览器发送的值作比较,若是发现A发生了变化就把A返回给浏览器(200),若是发现A没有变化就给浏览器返回一个304未修改。这样经过控制浏览器端的缓存,能够节省服务器的带宽,由于服务器不须要每次都把全量数据返回给客户端。浏览器
首部字段Etag能告知客户端实体标识。它是一种可将资源以字符串形式做为惟一性标识的方式。服务器会为每份资源分配对应的ETag值。 当资源更新时,Etag的值也须要更新。生成Etag值时没有统一的算法规则,而仅仅是有服务器来分配。缓存
首部字段
If-None-Match
属于附带条件之一.服务器
对于GET 和 HEAD 请求方法来讲,当且仅当服务器上没有任何资源的 ETag 属性值与这个首部中列出的相匹配的时候,服务器端会才返回所请求的资源,响应码为 200 .学习
对于 GET 和 HEAD 方法来讲,当验证失败的时候,服务器端必须返回响应码 304 (Not Modified,未改变)。对于可以引起服务器状态改变的方法,则返回 412 (Precondition Failed,前置条件失败)。须要注意的是,服务器端在生成状态码为 304 的响应的时候,必须同时生成如下会存在于对应的 200 响应中的首部:Cache-Control、Content-Location、Date、ETag、Expires 和 Vary 。code