learn-nginx icon indicating copy to clipboard operation
learn-nginx copied to clipboard

【proxy_pass 】关于proxy_pass ,各大AI回答都有谬误

Open cvpv opened this issue 11 months ago • 2 comments

因为没有讨论区,我就在这里发表讨论意见了,如果不允许,请回复我后我会自行删除

测试各大AI发现,基本AI对proxy_pass 的描述都有错误,经过我测试用下面的问题去问AI,100%都会说下面的配置有差别

    server {
        listen 59212;
        server_name localhost;
        location /manage/ {
            proxy_pass http://127.0.0.1:7001/manage/;
        }
    }
    server {
        listen 59213;
        server_name localhost;
        location /manage/ {
            proxy_pass http://127.0.0.1:7001;
        }
    }

但是经过我实际测试, 前端访问http://127.0.0.1:59212/manage/1234http://127.0.0.1:59213/manage/1234时,后端接收到的路径都是一样的,是/manage/1234

cvpv avatar Dec 09 '24 10:12 cvpv

是因为NGINX版本不一致,造成行为不一致吗?我测试的nginx版本是nginx-1.22.0

cvpv avatar Dec 09 '24 10:12 cvpv

# docker run --rm --name nginx-test -v $(pwd)/nginx.conf:/etc/nginx/conf.d/server.conf -p 8080:8080 nginx:1.22.0
server {
    listen 8080 default_server;
    server_name _;

    location /proxy-by-no-uri/ {
        proxy_pass http://127.0.0.1:8081;
    }
    location /proxy-by-uri/ {
        proxy_pass http://127.0.0.1:8081/proxy;
    }
    location /proxy-by-uri2/ {
        proxy_pass http://127.0.0.1:8081/proxy/;
    }
    
    location /ping {
        return 200 "pong";
    }
}


server {
    listen 8081;

    location / {
        return 200 "$uri";
    }
}

根据上面的配置,测试以下 case :

  • /proxy-by-no-path/ - 在 proxy_pass 代理时没有添加 URI ,那么会把原始所有请求路径追加到目标服务中去
    • [x] 127.0.0.1:8080/proxy-by-no-uri/ -> /proxy-by-no-uri/
    • [x] 127.0.0.1:8080/proxy-by-no-uri/a/b/c -> /proxy-by-no-uri/a/b/c
  • /proxy-by-uri/ - 在 proxy_pass 代理时添加了 URI , 那么会把 location 匹配后面的路径拼接到服务中去。请注意,这里和 location 的结尾没有对应,代理的 URI 没有以 / 结尾。
    • [x] 127.0.0.1:8080/proxy-by-uri/ -> /proxy
    • [x] 127.0.0.1:8080/proxy-by-uri/a/b/c/d -> /proxya/b/c/d ,注意这里的 a/b/c/dlocation 匹配后剩余的路径,由于 proxy_pass 服务时没有和 location 结尾对应,导致这里拼接会有问题
  • /proxy-by-uri2/ - 在 proxy_pass 代理时添加了 URI ,且两者结尾对应,在代理时会把 location 剩余的路径拼到服务中去。
    • [x] 127.0.0.1:8080/proxy-by-uri2/ -> /proxy/ ,其实这里是完整匹配了,没有拼任何路径
    • [x] 127.0.0.1:8080/proxy-by-uri2/a/b -> /proxy/a/b ,注意这里才是正常的

而你说的一样,其实不是『真一样』。因为你的 manage 目录名是一样的,导致没法区分这个问题。

location /manage/ {
    # 由于你这里带了 URI ,访问会把 location 剩余的拼到这里。没问题
    proxy_pass http://127.0.0.1:7001/manage/;
}

location /manage/ {
    # 由于你没有带 URI ,访问会把用户完整的拼到这里。也没有问题。。主要你的目录是一样的。
    proxy_pass http://127.0.0.1:7001;
}

ping @cvpv 你可以写些 case 真实的理解了这个的问题所在~

xuexb avatar Dec 26 '24 14:12 xuexb