最近在跟後臺對接口時,發現請求同一個接口時老是一次成功一次失敗這樣間隔着來,非常困擾。請求失敗的時候報的錯時
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