Nginx學(xué)習(xí):HTTP核心模塊(九)瀏覽器緩存與try_files瀏覽器緩存在 Nginx 的 HTTP 核心模塊中其實(shí)只有兩個(gè)簡單的配置,這一塊也是 HTTP 的基礎(chǔ)知識(shí)。之前我們就一直在強(qiáng)調(diào),學(xué)習(xí) Nginx 需要的就是各種網(wǎng)絡(luò)相關(guān)的基礎(chǔ)知識(shí),其中更重要的就是 HTTP 和 TCP 相關(guān)的內(nèi)容。另外一個(gè) try_files 配置指令也是 Nginx 中非常常用的一個(gè)指令,用于找不到指定的路徑文件時(shí),可以去按順序查找備用的一些文件路徑,非常實(shí)用。 瀏覽器緩存在 HTTP 協(xié)議中,有許多和瀏覽器緩存有關(guān)的選項(xiàng),而在 Nginx 的核心配置中,也有兩個(gè)與之相關(guān)的配置。 if_modified_sinceif_modified_since 是由瀏覽器發(fā)送的,讓服務(wù)端來判斷返回 200 還是 304 ,在 Nginx 中,它用于指定響應(yīng)的修改時(shí)間與 if_modified_since 請(qǐng)求頭的比較方法。
默認(rèn)值是 exact ,每個(gè)選項(xiàng)分別代表:
etagetag 是由服務(wù)器端生成的,客戶端通過發(fā)送 If-Match 或者 If-None-Match 這個(gè)條件判斷請(qǐng)求來驗(yàn)證資源是否修改。Nginx 中,這個(gè)配置可以開啟或關(guān)閉為靜態(tài)文件自動(dòng)計(jì)算 “ETag” 響應(yīng)頭。
它的默認(rèn)值是 on 。 測試正常情況下,我們第一次打開某個(gè)靜態(tài)頁面,是沒有 if_modified_since 的,服務(wù)端會(huì)返回 ETag 和 Last-Modified 以及 200 狀態(tài)碼。 然后第二次請(qǐng)求的時(shí)候,瀏覽器就會(huì)帶上 if_modified_since ,服務(wù)端會(huì)返回 304 表示使用本地緩存就可以了。 這是在默認(rèn)情況下。現(xiàn)在我們修改 Nginx 的配置,先將 if_modified_since 設(shè)置為 off ,然后強(qiáng)刷頁面之后再進(jìn)行普通刷新 ,會(huì)發(fā)現(xiàn)不管是強(qiáng)刷還是普通刷新,響應(yīng)頭和請(qǐng)求雖然沒有什么變化,但服務(wù)端都只會(huì)返回 200 了。也就是說,服務(wù)端不會(huì)去比較瀏覽器發(fā)送過來的 if_modified_since 值來判斷是否返回 304 。 接下來測試 etag ,這個(gè)就麻煩一點(diǎn),首先,我們要將 if_modified_since 設(shè)置為 before ,意思就是訪問的靜態(tài)資源文件的修改時(shí)間小于當(dāng)前瀏覽器提供的 If-Modified-Since 時(shí),才返回 200 。這樣的話,如果我們手動(dòng)修改文件的時(shí)間,將時(shí)間修改到當(dāng)前時(shí)間之后很長的一段時(shí)間,那么就可以讓瀏覽器在非強(qiáng)刷的狀態(tài)下一直返回 304 。
默認(rèn) etag 為 on 的情況下,你再次修改文件的時(shí)間,依然會(huì)正常返回一次 200 。這就是 etag 的作用,它是根據(jù)文件一些屬性進(jìn)行綜合 Hash 從而返回一個(gè)值,客戶端保存上回的 etag 值后傳送到服務(wù)端進(jìn)行比對(duì)。而如果現(xiàn)在你將 etag 設(shè)置為 off 的話,那么再次請(qǐng)求就不會(huì)有 Etag 響應(yīng)頭返回了,這時(shí)修改文件的時(shí)間,甚至是修改文件的內(nèi)容(注意修改內(nèi)容后還要手動(dòng)修改一下文件的修改時(shí)間,否則 if_modified_since 就會(huì)生效返回 200 了),后面的請(qǐng)求也將一直會(huì)是 304 (非強(qiáng)刷)。 ps.瀏覽器強(qiáng)刷其實(shí)就是瀏覽器不帶任何和 HTTP 緩存有關(guān)的請(qǐng)求頭進(jìn)行一次請(qǐng)求訪問。 Etag 最主要解決的其實(shí)是 if_modified_since 的一些缺點(diǎn),比如說有些時(shí)候可能我們只是周期性地修改一下文件,但文件內(nèi)容不發(fā)生變化(只是文件修改時(shí)間變動(dòng)),這時(shí)其實(shí)可以不用重新 200 響應(yīng)的。另外還有 if_modified_since 只支持到秒級(jí),而 Etag 的 Hash 變化是跟隨文件變動(dòng)的,因此它的粒度更細(xì)一些。還有一種情況就是某些服務(wù)器不能精確的得到文件的最后修改時(shí)間,這也會(huì)導(dǎo)致 if_modified_since 產(chǎn)生問題,更典型的就是客戶端時(shí)間和服務(wù)器時(shí)間不同步,比如有的人的電腦可能時(shí)間一直就是錯(cuò)的。 這一塊的內(nèi)容是 HTTP 的基礎(chǔ)知識(shí),而且寫文字也不太好描述怎么測試,大家可以關(guān)注下后期的視頻哈,在視頻中咱們?cè)俸煤醚菔尽?/p> try_files按指定順序檢查文件是否存在,并且使用第一個(gè)找到的文件來處理請(qǐng)求,那么處理過程就是在當(dāng)前上下文環(huán)境中進(jìn)行的。
其實(shí)就是我們不確定用戶訪問的路徑或者文件存不存在,這時(shí)可以按照 try_files 指定的順序來展示指定的 URI ,通常它都會(huì)和 文件路徑是根據(jù) root 指令和 alias 指令,將 file 參數(shù)拼接而成。 可以在名字尾部添加斜線以檢查目錄是否存在,比如“$uri/”。 如果找不到任何文件,將按最后一個(gè)參數(shù)指定的uri進(jìn)行內(nèi)部跳轉(zhuǎn)。 比如:
現(xiàn)在試試訪問 /tf1 ,會(huì)發(fā)現(xiàn)顯示的是 50x.php 的內(nèi)容,如果 /tf1 下面有頁面的話,那么直接訪問就可以查看到指定的頁面。這種感覺是不是有點(diǎn)像 error_page ,其實(shí)上面的內(nèi)容就相當(dāng)于是下面這樣的代碼。
這下就看出來了吧,try_files 按順序,如果第一個(gè)
在 tf2 目錄下,建立了兩個(gè)文件,然后訪問 /tf2 ,會(huì)顯示 1.html 的內(nèi)容,訪問 /tf2/2.html ,正常顯示 2.html 的內(nèi)容,按順序來說
隨便訪問 /tf3 或者目錄中的任意不存在的路徑,我這里會(huì)彈出下載,查看請(qǐng)求 Content-Type 會(huì)變成 application/octet-stream ,下載的文件是 php 的源碼。注意,這里是個(gè)坑點(diǎn),不要在靜態(tài)配置中進(jìn)行這樣的 try_files 。換成帶 PHP 相關(guān)配置的再試試。
現(xiàn)在訪問 /tf4 會(huì)顯示到最外面那個(gè)我們之前測試的時(shí)候打印所有
訪問 /tf5 或者 /tf5/xxx.html ,都會(huì)打開 tf5php 目錄下的 index.php 文件。注意,這里演示的是從 靜態(tài) 文件到 php 文件,如果是 /tf5/xxx.php 則會(huì)被之前我們配置過的 我們?cè)賮砜纯错憫?yīng)碼的問題。
這一段表示的是如果前面 uri... 部分都沒有匹配到,那么就會(huì)返回 401 的狀態(tài)碼。大家可以自己試一下訪問 /tf6 下的任意文件,最后返回的都是 401 狀態(tài)。 好了,我們?cè)賮砜匆幌?Laravel 文檔中給的一個(gè) Nginx 配置,其中有一段內(nèi)容是大部分 PHP 應(yīng)用在部署的時(shí)候也都會(huì)要求寫上的。
在全局的 location 中,訪問 uri 頁面或者 uri/ 目錄,找不到文件的話,會(huì)轉(zhuǎn)給 /index.php,并且把請(qǐng)求行的 GET 參數(shù)轉(zhuǎn)給 /index.php 文件。通?,F(xiàn)代化的框架都是單一入口,index.php 總是可以接收請(qǐng)求的,如果確實(shí)還是找不到,也將由 PHP 應(yīng)用來進(jìn)行對(duì)應(yīng)的 404 或者 500 處理。 另外,try_files 還可以做一件非常常見的事,就是顯示默認(rèn)圖片。
正常的圖片路徑找不到圖片了,就使用默認(rèn)的圖片來代替,這也是很多網(wǎng)站的基本需求。 總結(jié)今天的內(nèi)容不難吧,加起來就是三個(gè)配置項(xiàng),不過我們做了很多的測試。緩存對(duì)于現(xiàn)代化的 Web 開發(fā)來說非常重要,而 HTTP 緩存則是最前端的面向客戶一級(jí)的緩存。對(duì)于靜態(tài)資源來說,有著非常重要的作用,可以大大減少服務(wù)器的壓力。而 try_files 的靈活則為我們帶來了更多的特色功能,類似于默認(rèn)圖片這類的配置都能夠非常簡單方便。 不過估計(jì)大家平??赡軐?duì)這幾個(gè)指令用得也并不多,畢竟緩存那兩個(gè)都有默認(rèn)值,我們保持默認(rèn)就好了。而 try_files 通常最多的就是用在上文所說的全局路徑的處理上,是使用 Laravel 時(shí)必備的一個(gè)配置。但是,通過今天的學(xué)習(xí),相信咱們將來在需要的時(shí)候,也能馬上想起來這些配置指令的用法,能夠更加靈活自如的運(yùn)用它們。學(xué)習(xí),就是這樣一步一步的不斷積累,一次一次的不停實(shí)踐。 參考文檔: http:///en/docs/http/ngx_http_core_module.html |
|