ref:
https://blog.othree.net/log/2012/12/22/cache-control-and-etag/ << 建議讀一下
http://zhangxiaofei576342.blog.163.com/blog/static/2086199020101026113241602/
http://blog.toright.com/posts/3414/%E5%88%9D%E6%8E%A2-http-1-1-cache-%E6%A9%9F%E5%88%B6.html
Cache-Control header
優先級(由高至低):
no-store >> 完全不存下來,所以完全沒有 cache
no-cache >> 還是可能會 cache,但還是會每次都問有沒有新內容
max-age=60 >> 在 60 秒內不會再 request
ref:
http://tools.ietf.org/html/rfc2616#section-14.9
http://www.php-oa.com/2008/12/03/http-head.html
Cache Middleware
如果有啟用 Django 的 cache middleware(例如 UpdateCacheMiddleware 和 FetchFromCacheMiddleware)
每一個 request 都會被標上 Cache-Control: max-age=600
那個 600 是根據 CACHE_MIDDLEWARE_SECONDS
只要設置了 max-age > 0
response header 中就會被自動加入 Cache-Control
、Expires
和 Last-Modified
兩個欄位
ref:
https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-CACHE_MIDDLEWARE_SECONDS
@never_cache decorator
from django.views.decorators.cache import never_cache @never_cache def myview(request): pass
如果你單純的就是不希望被 cache
就使用這種方式
上面這個 decorator 只會設置 Cache-Control: max-age=0
max-age=0
是馬上過期
@cache_control decorator
from django.views.decorators.cache import cache_control class SongDetail(SVAPIDetailView): serializer_class = api_serializers.SongDetailSerializer @cache_control(no_store=True, no_cache=True, max_age=0) def get(self, request, song_id): do_something() return Response(data)
不知道為什麼,只設置 no-store 和 no-cache 的話
iOS 的 AFNetworking 還是會 cache
照道理說 no-store 的優先權應該是最高的
目前的解法是使用 Cache-Control: max-age=0
ref:
https://docs.djangoproject.com/en/dev/topics/cache/#controlling-cache-using-other-headers
Last-Modified 和 Etag
Last-Modified 要跟 response 的 If-Modified-Since 一起用
ETag 要跟 response 的 If-None-Match 一起用
Last-Modified 是說這個 URI 在什麼時候被修改了
是 GMT 時間
ETag 是 Entity Tag
是這個 URI 的 hash 值(但是用什麼來 hash 你可以自己決定,檔案內容之類的)
因為 hash 可能是個耗時的操作
所以 YSlow 建議不要用 ETag
用 Last-Modified、Expires 或 Cache-Control: max-age=xxx 就可以了
Vary header
Varnish, Squid 這一類的 cache proxy 多半會根據 URL 和 Vary header 提到的 header 來做一個 hash
用這個 hash 來判斷緩存有沒有命中
Vary header 可能會長這樣:
Vary: Accept-Encoding Vary: Accept-Encoding,User-Agent Vary: X-Some-Custom-Header,Host Vary: *
假設有兩個 requests 請求同一個檔案(URL 一樣)
但是這兩個 requests 的 User-Agent 不同(比如說是兩個不同的 browser)
第二個 request 的緩存就不會命中
因為 hash 結果會不一樣