<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系統、金蝶與條碼系統對接、用友與條碼系統對接

    前面我們在 (五) 中提到,在一個 location 中使用 content 階段指令時,通常情況下就是對應的 Nginx 模塊注冊該 location 中的“內容處理程序”。那么當一個 location 中未使用任何 content 階段的指令,即沒有模塊注冊“內容處理程序”時,content 階段會發生什么事情呢?誰又來擔負起生成內容和輸出響應的重擔呢?答案就是那些把當前請求的 URI 映射到文件系統的靜態資源服務模塊。當存在“內容處理程序”時,這些靜態資源服務模塊并不會起作用;反之,請求的處理權就會自動落到這些模塊上。

     

        Nginx 一般會在 content 階段安排三個這樣的靜態資源服務模塊(除非你的 Nginx 在構造時顯式禁用了這三個模塊中的一個或者多個,又或者啟用了這種類型的其他模塊)。按照它們在 content 階段的運行順序,依次是 ngx_index 模塊,ngx_autoindex 模塊,以及 ngx_static 模塊。下面就來逐一介紹一下這三個模塊。

     

        ngx_index 和 ngx_autoindex 模塊都只會作用于那些 URI 以 / 結尾的請求,例如請求 GET /cats/,而對于不以 / 結尾的請求則會直接忽略,同時把處理權移交給 content 階段的下一個模塊。而 ngx_static 模塊則剛好相反,直接忽略那些 URI 以 / 結尾的請求。

     

        ngx_index 模塊主要用于在文件系統目錄中自動查找指定的首頁文件,類似 index.html 和 index.htm 這樣的,例如:

        location / {
            root /var/www/;
            index index.htm index.html;
        }

    這樣,當用戶請求 / 地址時,Nginx 就會自動在 root 配置指令指定的文件系統目錄下依次尋找 index.htm 和index.html 這兩個文件。如果 index.htm 文件存在,則直接發起“內部跳轉”到 /index.htm 這個新的地址;而如果 index.htm 文件不存在,則繼續檢查 index.html 是否存在。如果存在,同樣發起“內部跳轉”到/index.html;如果 index.html 文件仍然不存在,則放棄處理權給 content 階段的下一個模塊。

     

        我們前面已經在 Nginx 變量漫談(二) 中提到, echo_exec 指令和 rewrite 指令可以發起“內部跳轉”。這種跳轉會自動修改當前請求的 URI,并且重新匹配與之對應的 location 配置塊,再重新執行rewriteaccesscontent 等處理階段。因為是“內部跳轉”,所以有別于 HTTP 協議中定義的基于 302 和 301 響應的“外部跳轉”,最終用戶的瀏覽器的地址欄也不會發生變化,依然是原來的 URI 位置。而ngx_index 模塊一旦找到了 index 指令中列舉的文件之后,就會發起這樣的“內部跳轉”,仿佛用戶是直接請求的這個文件所對應的 URI 一樣。

     

        為了進一步確認 ngx_index 模塊在找到文件時的“內部跳轉”行為,我們不妨設計下面這個小例子:

        location / {
            root /var/www/;
            index index.html;
        }
     
        location /index.html {
            set $a 32;
            echo "a = $a";
        }

    此時我們在本機的 /var/www/ 目錄下創建一個空白的 index.html 文件,并確保該文件的權限設置對于運行 Nginx worker 進程的帳戶可讀。然后我們來請求一下根位置(/):

        $ curl 'http://localhost:8080/'
        a = 32

    這里發生了什么?為什么輸出不是 index.html 文件的內容(即空白)?首先對于用戶的原始請求 GET /,Nginx 匹配出 location / 來處理它,然后 content 階段的 ngx_index 模塊在 /var/www/ 下找到了index.html,于是立即發起一個到 /index.html 位置的“內部跳轉”。

     

        到這里,相信大家都不會有問題。接下來有趣的事情發生了!在重新為 /index.html 這個新位置匹配location 配置塊時,location /index.html 的優先級要高于 location /,因為 location 塊按照 URI 前綴來匹配時遵循所謂的“最長子串匹配語義”。這樣,在進入 location /index.html 配置塊之后,又重新開始執行rewrite 、access、以及 content 等階段。最終輸出 a = 32 自然也就在情理之中了。

     

        我們接著研究上面這個例子。如果此時把 /var/www/index.html 文件刪除,再訪問 / 又會發生什么事情呢?答案是返回 403 Forbidden 出錯頁。為什么呢?因為 ngx_index 模塊找不到 index 指令指定的文件(在這里就是 index.html),接著把處理權轉給 content 階段的后續模塊,而后續的模塊也都無法處理這個請求,于是 Nginx 只好放棄,輸出了錯誤頁,并且在 Nginx 錯誤日志中留下了類似這一行信息:

        [error] 28789#0: *1 directory index of "/var/www/" is forbidden

    所謂 directory index 便是生成“目錄索引”的意思,典型的方式就是生成一個網頁,上面列舉出 /var/www/目錄下的所有文件和子目錄。而運行在 ngx_index 模塊之后的 ngx_autoindex 模塊就可以用于自動生成這樣的“目錄索引”網頁。我們來把上例修改一下:

        location / {
            root /var/www/;
            index index.html;
            autoindex on;
        }

    此時仍然保持文件系統中的 /var/www/index.html 文件不存在。我們再訪問 / 位置時,就會得到一張漂亮的網頁:

        $ curl 'http://localhost:8080/'
        <html>
        <head><title>Index of /</title></head>
        <body bgcolor="white">
        <h1>Index of /</h1><hr><pre><a href="../">../</a>
        <a href="cgi-bin/">cgi-bin/</a>  08-Mar-2010 19:36   -
        <a href="error/">error/</a>      08-Mar-2010 19:36   -
        <a href="htdocs/">htdocs/</a>    05-Apr-2010 03:55   -
        <a href="icons/">icons/</a>      08-Mar-2010 19:36   -
        </pre><hr></body>
        </html>

    生成的 HTML 源碼顯示,我本機的 /var/www/ 目錄下還有 cgi-bin/error/htdocs/, 以及 icons/ 這幾個子目錄。在你的系統中嘗試上面的例子,輸出很可能會不太一樣。

     

        值得一提的是,當你的文件系統中存在 /var/www/index.html 時,優先運行的 ngx_index 模塊就會發起“內部跳轉”,根本輪不到 ngx_autoindex 執行。感興趣的讀者可以自己測試一下。

     

        在 content 階段默認“墊底”的最后一個模塊便是極為常用的 ngx_static 模塊。這個模塊主要實現服務靜態文件的功能。比方說,一個網站的靜態資源,包括靜態 .html 文件、靜態 .css 文件、靜態 .js 文件、以及靜態圖片文件等等,全部可以通過這個模塊對外服務。前面介紹的 ngx_index 模塊雖然可以在指定的首頁文件存在時發起“內部跳轉”,但真正把相應的首頁文件服務出去(即把該文件的內容作為響應體數據輸出,并設置相應的響應頭),還是得靠這個 ngx_static 模塊來完成。

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