dmli的博客小屋

专注IT运维

nginx proxy中的几个斜杠"/"

测试环境遇到个nginx大坑,记录一下,共勉!

nginx proxy配置大家都很熟了,遇坑配置如下

server {
        listen 80;
        server_name example.com;
        location ~ /file {
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-Scheme $scheme;
            proxy_pass http://localhost:8080;
        }
        location ~ /image {
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-Scheme $scheme;
            proxy_pass http://localhost:8088;
        }

前端是nginx,后端为2个java应用程序,现在需要访问

http://example.com/image/path/file_test.html ,网页提示404无法找到;

http://example.com:8080/image/path/file_test.html ,网页显示正常,返回200。

原因分析:

既然直接访问后端服务器可以正常返回,那问题肯定出在nginx转发上了。经过各种测试,终于找打了原因:

url匹配到了第一个location!

因为location我这里加了一个 “~”符号,表示“区分大小写的正则匹配”,那么由于url中含有“file”字符串,直接就匹配第一条location了,导致返回404文件不存在。

解决方案:

一、将正则匹配“~”去掉,变成文本匹配:

server {
        listen 80;
        server_name example.com;
        location /file {
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-Scheme $scheme;
            proxy_pass http://localhost:8080;
        }
        location /image {
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-Scheme $scheme;
            proxy_pass http://localhost:8088;
        }

二、在路径后面加斜杠“/”,匹配精确路径:

server {
        listen 80;
        server_name example.com;
        location ~ /file/ {
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-Scheme $scheme;
            proxy_pass http://localhost:8080;
        }
        location ~ /image/ {
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-Scheme $scheme;
            proxy_pass http://localhost:8088;
        }

补充:

proxy_pass 后面连接加上斜杠,代表绝对路径,location中匹配的部分路径不会带到后端去,我们现在还是访问 http://example.com/image/path/file_test.html

情况1

location /image/ {
  proxy_pass http://localhost:8088;
}

得到后端地址为 http://localhost:8080/image/path/file_test.html

情况2

location /image/ {
  proxy_pass http://localhost:8088/;
}

得到后端地址为 http://localhost:8080/path/file_test.html

情况3

location /image/ {
  proxy_pass http://localhost:8088/backend;
}

得到后端地址为 http://localhost:8080/backendpath/file_test.html

情况4

location /image/ {
  proxy_pass http://localhost:8088/backend/;
}

得到的后端地址为 http://localhost:8080/backend/path/file_test.html

总结:

location中加斜杠,proxy_pass中不加斜杠,更符合我们直观的语义理解。

发表评论:

Copyright© dmli 2015-2019