使AJAX可緩存——基於flask

  主流瀏覽器都有緩存機制,主要基於HTTP協議定義的緩存策略。對於必定時間內不發生變更的文檔緩存起來,對於下次請求,就能夠直接返回緩存的結果。使用緩存有如下好處:javascript

一、減小冗餘的數據傳輸,節省網絡流量成本
二、減小加載時間,客戶可以快速加載頁面
三、減小對服務端的壓力,避免過載java

  咱們通常會爲靜態文件,如圖片,腳本,樣式表等設置緩存,這樣客戶端在下次請求時能夠減小沒必要要的網絡請求。實際上,咱們能夠把它用在全部組件上,包括Ajax響應,只要能夠確認結果不常常變更,就可使用緩存策略。redis

AJAX

  AJAX (Asynchronous JavaScript and XML)表示異步的javascript和XML,實際上,如今最著名的是JSON。Ajax可分爲主動請求和被動請求。被動請求指爲了未來使用而預先發起的,提早加載一些用戶可能用到的數據,來提升用戶體驗。主動請求,指基於用戶當前的操做而發起的請求。數據庫

  雖然AJAX是異步請求,可是對於主動請求,用戶任然須要等待響應。即使是被動請求可讓用戶感覺不到等待,可是仍然會有請求,產生流量,對服務端產生壓力。json

HTTP緩存策略

  HTTP協議經過Header來控制緩存的,包括請求和響應,這裏只講響應的緩存機制。響應緩存主要經過Expires頭和Cache-control頭來控制。下面按優先級由高到列出一些常見的緩存策略,:瀏覽器

  1. Cache-Control:no-store 不要緩存這個文檔
  2. Cache-Control:no-cache 保存文檔,可是須要與服務端再驗證才能使用
  3. Cache-control:max-age 緩存最長保存時間,單位是秒
  4. Expires:日期 根據日期判斷過時,因爲客戶端和服務器日期可能不一樣步,不推薦使用

 

緩存過時檢測

  爲了防止使用了過時的數據,必需要爲緩存設置過時時間,當緩存過時時,須要向服務器請求新的數據。但實際上,雖然緩存過時了,可是服務器的數文檔並無變更,並不須要返回整個文檔。所以客戶端可讓服務端在改變文檔的狀況下才發送整個文檔。這種特殊請求就是有條件的請求。條件請求通常使用Last-Modified/If-Modified-Since 和 Etag/If-None-Match。緩存

  Last-Modified表示文檔的最後修改日期,當緩存過時了,客戶端向服務器發送If-Modified-Since:Last-Modified的值進行條件請求,當服務端在這段時間沒有修改文檔,那麼就返回不包含主體的304響應,不然就返回新的文檔。服務器

   ETag 則是一個惟一文件標識符,每次文件修改後都會生成一個新的 ETag,所以也能夠根據Etag的值來判斷文檔有沒有更新。和最後修改時間檢測相似。網絡

  若是響應首部僅包含Last-Modified,就使用If-Modified-Since驗證,若是僅包含ETag,那麼使用If-None-Match來驗證。若是二者都提供了,那麼客戶端就應該同時發送兩種驗證。app

基於Flask的緩存響應

 

def make_cache_control_response(json_data):
    #json_data可能來自數據庫或者服務端緩存(如redis等),也多是新生成的json數據
    resp = make_response()
    resp.headers['Content-Type'] = 'application/json'
    resp.cache_control.max_age = 600 #最長緩存600秒
    if json_data.get('from_cache'):  #來自服務端緩存
        del json_data['from_cache']
        last_modified = json_data.get('cache_time', 0)
        if last_modified:
            del json_data['cache_time']
            resp.last_modified = datetime.fromtimestamp(last_modified) #添加Last-Moditified頭
    if not resp.last_modified:
        resp.last_modified = datetime.now()

    if request.if_modified_since and request.if_modified_since >= resp.last_modified: #若是是條件請求,而且緩存未過時,返回304響應
        return resp, 304
    resp.data = json.dumps(json_data)
    return resp, 200
相關文章
相關標籤/搜索