domo

domo

在nginx中,路径的匹配是一个重要的问题。当请求到达nginx服务器时,nginx会根据配置文件中的规则来匹配请求的路径。这个匹配过程是按照顺序进行的,直到找到第一个匹配的规则为止。因此,正确配置路径的匹配规则对于保证网站的正常运行非常重要。

前言#

與 nginx 的打交道很多,經常遇到 404 問題,每次出現都需要查資料才能寫出結果。這次來總結一下。

問題#

訪問的域名是 localhost/store/add_order.html
web 根目錄是 /www/web
store 是子目錄。

解決#

配置如下
默認路徑 (Mac)

/usr/local/etc/nginx/nginx.conf
server {
    listen       80;
    server_name  localhost;
    root   /www/web;
    #charset koi8-r;
    location / {
        index  index.php index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        fastcgi_pass   php:9000;
        fastcgi_index  index.php;
        include        fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    }

    location ^~ /api/ { 
        proxy_pass http://www.api.com/; 
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

以上 location 存在 3 個匹配規則

最先匹配 location = /50x.html
再次匹配 location ~ .php$
最後 匹配 /

例如 http://localhost/store/add-order.html

將去 /www/web 目錄下尋找 store/add-order.html 文件。

例如 http://localhost/store/add-order.php

將 /www/web 目錄下和 store/add-order.php 組合成 SCRIPT_FILENAME,傳遞給 php 組件。

代理#

例如 http://localhost/api/add-order.php

則代理成 http://www.api.com/add-order.php

但是如果 沒有寫 / 結尾,

proxy_pass http://www.api.com;

則代理成 http://www.api.com/api/add-order.php

補充#

location 用於匹配 url
它進行的是模糊匹配
沒有 “/” 時,location /abc/def 可以匹配 /abc/defghi 請求,也可以匹配 /abc/def/ghi 等
而有 “/” 時,location /abc/def/ 不能匹配 /abc/defghi 請求,只能匹配 /abc/def/anything 這樣的請求

擴展#

location = / {
   #規則A
}
location = /login {
   #規則B
}
location ^~ /static/ {
   #規則C
}
location ~ \.(gif|jpg|png|js|css)$ {
   #規則D,注意:是根據括號內的大小寫進行匹配。括號內全是小寫,只匹配小寫
}
location ~* \.png$ {
   #規則E
}
location !~ \.xhtml$ {
   #規則F
}
location !~* \.xhtml$ {
   #規則G
}
location / {
   #規則H
}

那麼產生的效果如下:

訪問根目錄 /, 比如http://localhost/ 將匹配規則 A

訪問 http://localhost/login 將匹配規則 B,http://localhost/register 則匹配規則 H

訪問 http://localhost/static/a.html 將匹配規則 C

訪問 http://localhost/a.gif, http://localhost/b.jpg 將匹配規則 D 和規則 E,但是規則 D 順序優先,規則 E 不起作用, 而 http://localhost/static/c.png 則優先匹配到 規則 C

訪問 http://localhost/a.PNG 則匹配規則 E, 而不會匹配規則 D,因為規則 E 不區分大小寫。

訪問 http://localhost/a.xhtml 不會匹配規則 F 和規則 G,

http://localhost/a.XHTML 不會匹配規則 G,(因為!)。規則 F,規則 G 屬於排除法,符合匹配規則也不會匹配到,所以想想看實際應用中哪裡會用到。

訪問 http://localhost/category/id/1111 則最終匹配到規則 H,因為以上規則都不匹配,這個時候 nginx 轉發請求給後端應用伺服器,比如 FastCGI(php),tomcat(jsp),nginx 作為方向代理伺服器存在。

優先級:(location =) > (location 完整路徑 ) > (location ^~ 路徑) > (location ~,~* 從上向下正則順序,匹配在最後一條終止) > (location 部分起始路徑) > (/)

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。