我已经在我开发的URL缩短API中实现了Google描述的HTTP Caching guidelines。
这是我发送回复的方式:
const urlResponseCacheControlMaxAge = 172800 // 2 days
type urlResponse struct {
LongURL string `json:"longUrl"`
ShortURL string `json:"shortUrl"`
}
func (u urlResponse) Hash() string {
parts := strings.Split(u.ShortURL, "/")
return parts[len(parts)-1]
}
func sendURLResponse(w http.ResponseWriter, req *http.Request, urlResponse *urlResponse) {
if eTag, ok := req.Header["ETag"]; ok && urlResponse.Hash() == eTag[0] {
w.WriteHeader(http.StatusNotModified)
io.WriteString(w, "")
return
}
cacheControl := fmt.Sprintf(
"max-age:%d, public",
urlResponseCacheControlMaxAge,
)
w.Header().Set("Cache-Control", cacheControl)
w.Header().Set("Content-Type", "application/json;charset=utf-8")
w.Header().Set("ETag", urlResponse.Hash())
w.WriteHeader(http.StatusOK)
encoder := json.NewEncoder(w)
err := encoder.Encode(urlResponse)
if err != nil {
SendError(w, NewError(
URLResponseEncoding,
"Error encoding response",
map[string]string{"error": err.Error()},
))
return
}
}
基本上,当浏览器向API发送请求(使用GET
)时,我在响应中返回ETag和Cache-Control标头;缓存控制标头将最长有效期设置为两天。
我希望发生的是,在后续请求中,浏览器使用了缓存的响应。两天后,浏览器应在请求标头中发送ETag,以检查响应是否已更改。
但是,我观察到的是每次我单击“提交”按钮时,浏览器都会重新发送请求。在Google Chrome开发者控制台上,我未选中“禁用缓存”,但每次仍然发送请求。
此外,浏览器没有将ETag和请求标头一起发送回去。
是否缺少某些导致缓存无法按预期工作的东西?
答案 0 :(得分:2)
cacheControl := fmt.Sprintf(
"max-age:%d, public",
Cache-Control
标头必须包含使用时的max-age=...
而不是max-age:...
的缓存时间(=
与:
)。您尝试以错误的方式设置的值将被忽略。
此外,浏览器不会将ETag和请求标头一起发回。
if eTag, ok := req.Header["ETag"]; ok && urlResponse.Hash() == eTag[0] {
w.WriteHeader(http.StatusNotModified)
浏览器不会在ETag
标头内发送回etag。此标头仅用于设置etag。相反,浏览器将要求服务器提供资源是否经过了比较比较,并通过将接收到的etag放入If-None-Match: ...
标头中来实现-含义:如果资源与给定etag不匹配,请返回资源。 / p>
答案 1 :(得分:0)
要使用 ETag 和浏览器发送 If-Modified-Since
和 If-None-Match
标头,缓存控件必须设置为 no-cache
。
服务器使用 Cache-Control: no-cache
header 或浏览器通过 Request.cache
option。