V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
NGINX
NGINX Trac
3rd Party Modules
Security Advisories
CHANGES
OpenResty
ngx_lua
Tengine
在线学习资源
NGINX 开发从入门到精通
NGINX Modules
ngx_echo
kyonn
V2EX  ›  NGINX

nginx rewrite 指令的问题

  •  
  •   kyonn · 30 天前 · 1612 次点击

    手头没有现成的测试环境,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 条附言  ·  29 天前
    实测 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  
       30 天前 via Android
    Nginx 甚至有 Windows 版。或者在 wsl 里启动一个。https://nginx.org/en/docs/windows.html

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

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

    实测 rewrite 不需要完全匹配,只要部分匹配了就会进行替换,且没匹配的部分直接被丢弃。另外,原始请求的查询参数会被直接追加到新请求上,除非 rewrite 的新字符串末尾增加?符号。
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2636 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 15:14 · PVG 23:14 · LAX 08:14 · JFK 11:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.