<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    Nginx 配置指令的執行順序(十一)

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    緊跟在 post-access 階段之后的是 try-files 階段。這個階段專門用于實現標準配置指令 try_files 的功能,并不支持 Nginx 模塊注冊處理程序。由于 try_files 指令在許多 FastCGI 應用的配置中都有用到,所以我們不妨在這里簡單介紹一下。

     

        try_files 指令接受兩個以上任意數量的參數,每個參數都指定了一個 URI. 這里假設配置了 N 個參數,則 Nginx 會在 try-files 階段,依次把前 N-1 個參數映射為文件系統上的對象(文件或者目錄),然后檢查這些對象是否存在。一旦 Nginx 發現某個文件系統對象存在,就會在 try-files 階段把當前請求的 URI 改寫為該對象所對應的參數 URI(但不會包含末尾的斜杠字符,也不會發生 “內部跳轉”)。如果前 N-1 個參數所對應的文件系統對象都不存在,try-files 階段就會立即發起“內部跳轉”到最后一個參數(即第 N 個參數)所指定的 URI.

     

        前面在 (六) 和 (七) 中已經看到靜態資源服務模塊會把當前請求的 URI 映射到文件系統,通過 root配置指令所指定的“文檔根目錄”進行映射。例如,當“文檔根目錄”是 /var/www/ 的時候,請求 URI/foo/bar 會被映射為文件 /var/www/foo/bar,而請求 URI /foo/baz/ 則會被映射為目錄 /var/www/foo/baz/. 注意這里是如何通過 URI 末尾的斜杠字符是否存在來區分“目錄”和“文件”的。我們正在討論的 try_files配置指令使用同樣的規則來完成其各個參數 URI 到文件系統對象的映射。

     

        不妨來看下面這個例子:

        root /var/www/;
     
        location /test {
            try_files /foo /bar/ /baz;
            echo "uri: $uri";
        }
     
        location /foo {
            echo foo;
        }
     
        location /bar/ {
            echo bar;
        }
     
        location /baz {
            echo baz;
        }

    這里通過 root 指令把“文檔根目錄”配置為 /var/www/,如果你系統中的 /var/www/ 路徑下存放有重要數據,則可以把它替換為其他任意路徑,但此路徑對運行 Nginx worker 進程的系統帳號至少有可讀權限。我們在location /test 中使用了 try_files 配置指令,并提供了三個參數,/foo/bar/ 和 /baz. 根據前面對try_files 指令的介紹,我們可以知道,它會在 try-files 階段依次檢查前兩個參數 /foo 和 /bar/ 所對應的文件系統對象是否存在。

     

        不妨先來做一組實驗。假設現在 /var/www/ 路徑下是空的,則第一個參數 /foo 映射成的文件/var/www/foo 是不存在的;同樣,對于第二個參數 /bar/ 所映射成的目錄 /var/www/bar/ 也是不存在的。于是此時 Nginx 會在 try-files 階段發起到最后一個參數所指定的 URI(即 /baz)的“內部跳轉”。實際的請求結果證實了這一點:

        $ curl localhost:8080/test
        baz

    顯然,該請求最終和 location /baz 綁定在一起,執行了輸出 baz 字符串的工作。上例中定義的 location /foo 和 location /bar/ 完全不會參與這里的運行過程,因為對于 try_files 的前 N-1 個參數,Nginx 只會檢查文件系統,而不會去執行 URI 與 location 之間的匹配。

     

        對于上面這個請求,Nginx 會產生類似下面這樣的“調試日志”:

        $ grep trying logs/error.log
        [debug] 3869#0: *1 trying to use file: "/foo" "/var/www/foo"
        [debug] 3869#0: *1 trying to use dir: "/bar" "/var/www/bar"
        [debug] 3869#0: *1 trying to use file: "/baz" "/var/www/baz"

    通過這些信息可以清楚地看到 try-files 階段發生的事情:Nginx 依次檢查了文件 /var/www/foo 和目錄/var/www/bar,末了又處理了最后一個參數 /baz. 這里最后一條“調試信息”容易產生誤解,會讓人誤以為 Nginx 也把最后一個參數 /baz 給映射成了文件系統對象進行檢查,事實并非如此。當 try_files 指令處理到它的最后一個參數時,總是直接執行“內部跳轉”,而不論其對應的文件系統對象是否存在。

     

        接下來再做一組實驗:在 /var/www/ 下創建一個名為 foo 的文件,其內容為 hello world(注意你需要有/var/www/ 目錄下的寫權限):

        $ echo 'hello world' > /var/www/foo

    然后再請求 /test 接口:

        $ curl localhost:8080/test
        uri: /foo

    這里發生了什么?我們來看,try_files 指令的第一個參數 /foo 可以映射為文件 /var/www/foo,而 Nginx 在try-files 階段發現此文件確實存在,于是立即把當前請求的 URI 改寫為這個參數的值,即 /foo,并且不再繼續檢查后面的參數,而直接運行后面的請求處理階段。

     

        上面這個請求在 try-files 階段所產生的“調試日志”如下:

        $ grep trying logs/error.log
        [debug] 4132#0: *1 trying to use file: "/foo" "/var/www/foo"

    顯然,在 try-files 階段,Nginx 確實只檢查和處理了 /foo 這一個參數,而后面的參數都被“短路”掉了。

     

        類似地,假設我們刪除剛才創建的 /var/www/foo 文件,而在 /var/www/ 下創建一個名為 bar 的子目錄:

        $ mkdir /var/www/bar

    則請求 /test 的結果也是類似的:

        $ curl localhost:8080/test
        uri: /bar

    在這種情況下,Nginx 在 try-files 階段發現第一個參數 /foo 對應的文件不存在,就會轉向檢查第二個參數對應的文件系統對象(在這里便是目錄 /var/www/bar/)。由于此目錄存在,Nginx 就會把當前請求的 URI 改寫為第二個參數的值,即 /bar(注意,原始參數值是 /bar/,但 try_files 會自動去除末尾的斜杠字符)。

     

        這一組實驗所產生的“調試日志”如下:

        $ grep trying logs/error.log
        [debug] 4223#0: *1 trying to use file: "/foo" "/var/www/foo"
        [debug] 4223#0: *1 trying to use dir: "/bar" "/var/www/bar"

    我們看到,try_files 指令在這里只檢查和處理了它的前兩個參數。

     

        通過前面這幾組實驗不難看到,try_files 指令本質上只是有條件地改寫當前請求的 URI,而這里說的“條件”其實就是文件系統上的對象是否存在。當“條件”都不滿足時,它就會無條件地發起一個指定的“內部跳轉”。當然,除了無條件地發起“內部跳轉”之外,try_files 指令還支持直接返回指定狀態碼的 HTTP 錯誤頁,例如:

        try_files /foo /bar/ =404;

    這行配置是說,當 /foo 和 /bar/ 參數所對應的文件系統對象都不存在時,就直接返回 404 Not Found 錯誤頁。注意這里它是如何使用等號字符前綴來標識 HTTP 狀態碼的。

    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全