Я реализовал рекомендации по кэшированию HTTP , описанные Google в API сокращения URL, который я разработал.
Вот как я отправляю ответ:
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заголовок в ответе;заголовок элемента управления кэшем устанавливает максимальный срок действия в два дня.
Я ожидаю, что в последующих запросах браузер использует кэшированный ответ.По истечении 2 дней браузер должен отправить ETag в заголовок запроса, чтобы проверить, изменился ли ответ.
Однако я наблюдаю, что каждый раз, когда я нажимаю кнопку отправки, браузерповторно отправляет запрос.На консоли разработчика Google Chrome я снял флажок «Отключить кэширование», и все же он каждый раз отправляет запросы.
Более того, браузер не отправляет ETag обратно с заголовками запросов.
Есть ли что-то, чего мне не хватает, из-за чего кеш не работает должным образом?