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