nginx rewrite 指令的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kyonn
V2EX    NGINX

nginx rewrite 指令的问题

  •  
  •   kyonn 70 天前 1860 次点击
    这是一个创建于 70 天前的主题,其中的信息可能已经有所发展或是发生改变。

    手头没有现成的测试环境,AI 的回答感觉也不太靠谱,咨询下 V 友 关于 nginx rewrite 指令的问题:

    一、rewrite 指令的正则表达式是部分匹配还是完全匹配才生效?

    比如下面的配置中,请求 /name/jane-lotus 肯定会触发 rewrite 指令,最终请求地址为 http://user-center/users?name=jane-lotus 。

    那么请求 /name/regions/bbb 会不会触发 rewrite 的 URI 替换?最终请求地址是多少?

    这篇文章说不会触发 rewrite ,AI 的回答是会触发 rewrite 。

    location /name/ { rewrite /name/([^/]+) /users?name=$1 break; proxy_passs http://user-center/main/basicinfo/; } 

    二、还是上面的配置,假如原始请求里带了查询参数,那么触发 rewrite 后会不会把原始请求参数也追加给新的请求地址? rewrite 新目标里有没有新的查询参数是否会影响老的查询参数追加到最终请求里?

    三、是否有比较系统的 nginx 配置教程推荐或者模拟测试环境验证 nginx 详细执行过程的方法?

    第 1 条附言    69 天前
    实测 rewrite 不需要完全匹配,只要部分匹配了就会进行替换,且没匹配的部分直接被丢弃。另外,原始请求的查询参数会被直接追加到新请求上,除非 rewrite 的新字符串末尾增加?符号。

    测试代码如下:
    docker exec -it nginx nginx -s reload && curl http://127.0.0.1/name/ggg/ccc?bb=cc

    ```
    worker_processes 1;
    worker_rlimit_nofile 8192;

    events {
    worker_connections 4096;
    }

    http {
    include /etc/nginx/mime.types;
    index index.html index.htm index.php;


    server {
    listen 80;
    server_name basic;
    access_log /dev/stdout;

    location / {
    proxy_pass http://httpbin.org;
    }
    location /deny {
    deny all;
    }
    location /name/ {
    rewrite /name/([^/]+) /users?name=$1 break;
    proxy_pass http://127.0.0.1:5448;
    }
    }


    server {
    listen 5448;
    server_name basic;
    access_log /dev/stdout;

    location / {
    add_header Content-Type text/plain;
    return 200 "$request_uri";
    }
    location /deny {
    deny all;
    }
    }

    }
    ```
    14 条回复    2025-08-03 10:52:54 +08:00
    ryd994
        1
    ryd994  
       70 天前 via Android
    Nginx 甚至有 Windows 版。或者在 wsl 里启动一个。https://nginx.org/en/docs/windows.html

    自己试一下比在这问快多了
    ysc3839
        2
    ysc3839  
       70 天前 via Android
    1.我认为是部分匹配。因为一种典型用法就是只写“^”匹配开头来实现任意匹配,如果要完全匹配的话,那显然只匹配一个开头是不满足的。
    2.印象中 rewrite 不匹配不改变$args ,与 try_files 不同,后者会覆盖掉$args ,所以用 try_files 时需要手动写上$args 。
    我不保证正确,建议还是实际测试。
    Lax
        3
    Lax  
       70 天前
    日常测试 nginx 配置用这个命令 docker run --rm -it -p 8080:80 -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro nginx
    kyonn
        4
    kyonn  
    OP
       70 天前 via Android
    @ryd994 部署一个 nginx 实例是快的,但是没办法看到完整的匹配过程,尤其是涉及多条规则的时候 看不到中间过程。不知道是否有解决办法
    kyonn
        5
    kyonn  
    OP
       70 天前 via Android
    @Lax 能有什么配置方法能看到完整的内部逻辑匹配过程吗?尤其是内部配置多次跳转时?
    Lax
        6
    Lax  
       70 天前
    回到你的问题,正则加上结束符$才能完整匹配。
    Lax
        7
    Lax  
       70 天前
    @kyonn 用到 break 了,不会多次跳转。改一下 log_format 到 debug 看看有没有你需要的信息。我调试的时候会 proxy_pass 到本地的另一个调试的 server ,然后用 echo 模块直接 `echo $request_uri;`,也可以显示其它信息,在命令行或浏览器里都方便调试。
    Lax
        8
    Lax  
       70 天前
    说错了,是 access_log 的 log_format 和 error_log 的 level 到 debug
    kyonn
        9
    kyonn  
    OP
       70 天前
    @Lax 了解。我试下。
    kyonn
        10
    kyonn  
    OP
       70 天前
    @ysc3839 好的。我测试下。
    Hanada
        11
    Hanada  
       69 天前 via Android
    @ysc3839 rewrite 虽然不匹配参数,但是可以改参数的,比如他这里,会追加一个 name 参数到原参数列表里面( rewrite 甚至帮你处理好?和&的拼接问题了)
    Hanada
        12
    Hanada  
       69 天前 via Android
    你这段配置确实很难第一时间理解处理逻辑……主要还是 nginx 太智能了,很多时候喜欢给你搞分场景自动处理。你这里的不仅仅在于 rewrite ,还有 location 和 proxy_pass 的 uri 拼接逻辑。
    实测之前基本上没人敢给你准确答案。
    比如
    1.proxy_pass 带变量和不带变量是两种处理逻辑
    2.proxy_pass 带 uri 和不带 uri 是两种处理逻辑
    4.location 用正则和非正则是两种处理逻辑
    Hanada
        13
    Hanada  
       69 天前 via Android   1
    如果想快速测试但是又不想起一个 nginx 实际的话,这里有一个网站可以让你调试,配两个 server 块,A server 发请求,B server 收请求并且输出$request_uri 就能看到结果了。https://tech-playground.com/playgrounds/nginx/
    kyonn
        14
    kyonn  
    OP
       69 天前
    @Hanada
    @Lax
    @ysc3839

    多谢,提供的验证方法十分方便。

    实测 rewrite 不需要完全匹配,只要部分匹配了就会进行替换,且没匹配的部分直接被丢弃。另外,原始请求的查询参数会被直接追加到新请求上,除非 rewrite 的新字符串末尾增加?符号。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1008 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 18:38 PVG 02:38 LAX 11:38 JFK 14:38
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86