前言#
與 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 部分起始路徑) > (/)