domo

domo

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

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。