1. 程式人生 > >nginx靜態資源緩存策略配置

nginx靜態資源緩存策略配置

什麽 html 重新 roo control 區分 oot regexp 引用

1. 問題-背景

以前也經常用nginx,但用的不深,通常是簡單的設置個location用來做反向代理。直到今天給客戶做項目碰到緩存問題:客戶有個app,只是用原生做了個殼,裏面的內容都是用h5寫的,我們半途接手將新版本靜態資源部署到服務器上後,發現手機端一直顯示老的頁面,一抓包,發現手機端根本就沒有去請求新的html頁面,定位是緩存問題。

2. 配置

乍一看,客戶原來的配置好像沒什麽問題,該有的也全有了

# 這是客戶原來的配置
server {
    listen       80 default_server;
    server_name  xxx.xxx.com;
    root         /app/xxx/html/mobile/;

    location ~ .*\.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm)$
    {
        expires      7d;
    }

    location ~ .*\.(?:js|css)$
    {
        expires      7d;
    }

    location ~ .*\.(?:htm|html)$
    {
        add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
    }

    location ^~/mobile/
    {
        alias /app/xxx/html/mobile/;
    }
}

乍看沒問題,但就是沒有生效,由於查找nginx文檔,發現nginx的location有優先級之分(是否生效與放置的位置沒有關系)。

2.1 nginx location的四種類別

【=】模式: location = path,此種模式優先級最高(但要全路徑匹配)
【^~】模式:location ^~ path,此種模式優先級第二高於正則;
【~ or ~*】模式:location ~ path,正則模式,優先級第三,【~】正則匹配區分大小寫,【~*】正則匹配不區分大小寫;
【path】模式: location path,中間什麽都不加,直接跟路徑表達式;
註意:一次請求只能匹配一個location,一旦匹配成功後,便不再繼續匹配其余location;

一對照,發現location ^~優先級高於那些正則的緩存策略,所以緩存策略肯定不會對其生效,一翻查找下,終於解決了,配置如下:

server {
    listen       80 default_server;
    server_name  xxx.xxx.com;
    root         /app/xxx/html/mobile/;

    location ~ .*\.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm)$
    {
        expires      7d;
    }

    location ~ .*\.(?:js|css)$
    {
        expires      7d;
    }

    location ~ .*\.(?:htm|html)$
    {
        add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
    }

    location ^~/mobile/
    {
        alias /app/xxx/html/mobile/;
    # 將緩存策略用if語句寫在location裏面,生效了
        if ($request_filename ~* .*\.(?:htm|html)$)
        {
            add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
        }

        if ($request_filename ~* .*\.(?:js|css)$)
        {
            expires      7d;
        }

        if ($request_filename ~* .*\.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm)$)
        {
            expires      7d;
        }
    }
}

4. 深化

項目通常就是靜態資源與接口,接口一般都很少碰到緩存問題(因為很少有人去給接口配置緩存策略,不配置的話就不緩存),碰到緩存問題的通常都是靜態資源。
靜態資源——html:
html文件最容易碰到緩存問題,重新發版後,一旦客戶端繼續使用原來的緩存,那麽在原來的緩存過期之前,沒有任何辦法去觸使客戶端更新,除非一個個通知android客戶手動清除app緩存數據,通知IOS用戶卸載重裝。所以配置html緩存策略時要格外小心,我們項目是不緩存html文件;
靜態資源——js/css/各種類型的圖片:
此類資源改動較少,為了提升用戶體驗,一般都需要配置緩存,但反而不容易碰到緩存問題。因為現在的前程工程也都需要build,在build時工具會自動在文件名上加時間戳,這樣一發新版時,只要客戶端請求了新版的html,裏面引用的js/css/jpg等都已經換了路徑,肯定也就不會使用本地的緩存了。

nginx靜態資源緩存策略配置