整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Nginx的Rewrite规则与实例

Nginx的Rewrite规则与实例

ginx的Rewrite规则与实例

Nginx Rewrite 规则相关指令

相关指令有if,rewrite,set,return,break等,其中最关键的就是rewrite.一个简单的Nginx Rewrite规则语法如下:

rewrite ^/b/(.*)\.html /play.php?video=break;

1.break指令

默认值:none ;使用环境:server,location,if ;

该指令的作用是完成当前的规则集,不再处理rewrite指令。

2.if指令

默认值:none ;使用环境:server,location

该指令用于检查一个条件是否符合,如果条件符合,则执行大括号内的语句。If指令不支持嵌套,不支持多个条件&&和||处理。

A.变量名,错误的值包括:空字符串""或者任何以0开始的字符串

B.变量比较可以使用"="(表示等于)和"!="(表示不等于)

C.正则表达式模式匹配可以使用"~*"和"~"符号

D."~"符号表示区分大小写字母的匹配

E."~*"符号表示不区分大小写字母的匹配

F."!~"和"!~*"符号的作用刚好和"~"、"~*"相反,表示不匹配

G."-f"和"!-f"用来判断文件是否存在

H."-d"和"!-d"用来判断目录是否存在

I."-e"和"!-e"用来判断文件或目录是否存在

J."-x"和"!-x"用来判断文件是否为可执行

K.部分正则表达式可以在()内,用~来访问

3.return指令

语法:return code ;使用环境:server,location,if ;

该指令用于结束规则的执行并返回状态码给客户端。

示例:如果访问的URL以".sh"或".bash"结尾,则返回403状态码

location ~ .*\.(sh|bash)?$

{

return 403;

}

ginx_Rewrite

  • 一、介绍Rewrite

Rewrite根据nginx提供的全局变量或自己设置的变量,结合正则表达式和标志位实现url重写和者重定向。

  • Rewrite和location类似,都可以实现跳转,区别是rewrite是在同一域名内更改url,而location是对同类型匹配路径做控制访问,或者proxy_pass代理到其他服务器。
  • Rewrite和location执行顺序:执行server下的rewrite执行location匹配执行location下的rewrite

  • 二、语法和参数说明

    • rewrite语法格式
    rewrite        <regex>        <replacement>        <flag>;
     关键字        正则表达式         代替的内容         重写类型
    
    Rewrite:一般都是rewrite
    Regex:可以是字符串或者正则来表示想要匹配的目标URL
    Replacement:将正则匹配的内容替换成replacement
    Flag:flag标示,重写类型:
      - last:本条规则匹配完成后,继续向下匹配新的location URI规则;相当于Apache里德(L)标记,表示完成rewrite,浏览器地址栏URL地址不变;一般写在server和if中;
      - break:本条规则匹配完成后,终止匹配,不再匹配后面的规则,浏览器地址栏URL地址不变;一般使用在location中;
      - redirect:返回302临时重定向,浏览器地址会显示跳转后的URL地址;
      - permanent:返回301永久重定向,浏览器地址栏会显示跳转后的URL地址;
    server {
      # 访问 /last.html 的时候,页面内容重写到 /index.html 中,并继续后面的匹配,浏览器地址栏URL地址不变
      rewrite /last.html /index.html last;
    
      # 访问 /break.html 的时候,页面内容重写到 /index.html 中,并停止后续的匹配,浏览器地址栏URL地址不变;
      rewrite /break.html /index.html break;
    
      # 访问 /redirect.html 的时候,页面直接302定向到 /index.html中,浏览器地址URL跳为index.html
      rewrite /redirect.html /index.html redirect;
    
      # 访问 /permanent.html 的时候,页面直接301定向到 /index.html中,浏览器地址URL跳为index.html
      rewrite /permanent.html /index.html permanent;
    
      # 把 /html/*.html=> /post/*.html ,301定向
      rewrite ^/html/(.+?).html$ /post/$1.html permanent;
    
      # 把 /search/key=> /search.html?keyword=key
      rewrite ^/search\/([^\/]+?)(\/|$) /search.html?keyword=$1 permanent;
      
      # 把当前域名的请求,跳转到新域名上,域名变化但路径不变
      rewrite ^/(.*) http://www.jd.com/$1 permanent;
      }
    if (表达式) {
    }
    
    #当表达式只是一个变量时,如果值为空或任何以0开头的字符串都会当做false直接比较变量和内容时,使用=或!=~正则表达式匹配,~*不区分大小写的匹配,!~区分大小写的不匹配
    
    $args :这个变量等于请求行中的参数,同$query_string
    $content_length : 请求头中的Content-length字段。
    $content_type : 请求头中的Content-Type字段。
    $document_root : 当前请求在root指令中指定的值。
    $host : 请求主机头字段,否则为服务器名称。
    $http_user_agent : 客户端agent信息
    $http_cookie : 客户端cookie信息
    $limit_rate : 这个变量可以限制连接速率。
    $request_method : 客户端请求的动作,通常为GET或POST。
    $remote_addr : 客户端的IP地址。
    $remote_port : 客户端的端口。
    $remote_user : 已经经过Auth Basic Module验证的用户名。
    $request_filename : 当前请求的文件路径,由root或alias指令与URI请求生成。
    $scheme : HTTP方法(如http,https)。
    $server_protocol : 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
    $server_addr : 服务器地址,在完成一次系统调用后可以确定这个值。
    $server_name : 服务器名称。
    $server_port : 请求到达服务器的端口号。
    $request_uri : 包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。
    $uri : 不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。
    $document_uri : 与$uri相同。
     
    例子:
    URL:http://localhost:81/download/stat.php?id=1585378&web_id=1585378
    Server_Dir:/var/www/html
    $host:localhost
    $server_port:81
    $request_uri:/download/stat.php?id=1585378&web_id=1585378
    $document_uri:/download/stat.php
    $document_root:/var/www/html
    $request_filename:/var/www/html/download/stat.php
    
    # 如果文件不存在则返回400
    if (!-f $request_filename) {
        return 400;
    }
    
    # 如果host是www.360buy.com,则301到www.jd.com中
    if ( $host !="www.jd.com" ){
        rewrite ^/(.*)$ https://www.jd.com/$1 permanent;
    }
    
    # 如果请求类型是POST则返回405,return不能返回301,302
    if ($request_method=POST) {
        return 405;
    }
    
    # 如果参数中有 a=1 则301到指定域名
    if ($args ~ a=1) {
        rewrite ^ http://example.com/ permanent;
    }
    - 文件名及参数重写
     location=/index.html {
     # 修改默认值为
     set $name test;
    
     # 如果参数中有 name=xx 则使用该值
     if ($args ~* name=(\w+?)(&|$)) {
         set $name $1;
     }
    
     # permanent 301重定向
     rewrite ^ /$name.html permanent;
    }
    
    - 隐藏真实目录
    server {
      root /var/www/html;
      # 用 /html_test 来掩饰 html
      location / {
          # 使用break拿一旦匹配成功则忽略后续location
          rewrite /html_test /html break;
      }
    
      # 访问真实地址直接报没权限
      location /html {
          return 403;
      }
    }


    - 禁止指定IP访问
     location / {
            if ($remote_addr=192.168.1.253) {
                    return 403;
            }
     }
    - 如果请求的文件不存在,则反向代理到localhost 。这里的break也是停止继续rewrite
    if (!-f $request_filename){
        break;
        proxy_pass http://127.0.0.1;
    }
    - 对/images/bla_500x400.jpg文件请求,重写到/resizer/bla.jpg?width=500&height=400地址,并会继续尝试匹配location。
    rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last;


    Proxy_Pass

    Proxy_pass反向代理,用的是nginx的Proxy模块。

    第一种:
    location /proxy/ {
        proxy_pass http://127.0.0.1/;
    }
    代理到URL:http://127.0.0.1/test.html
    
    
    第二种:
    location /proxy/ {
        proxy_pass http://127.0.0.1;  #少/
    }
    代理到URL:http://127.0.0.1/proxy/test.html
    
    
    第三种:
    location /proxy/ {
        proxy_pass http://127.0.0.1/aaa/;
    }
    代理到URL:http://127.0.0.1/aaa/test.html
    
    
    第四种(相对于第三种,最后少一个 / )
    location /proxy/ {
        proxy_pass http://127.0.0.1/aaa;
    }
    代理到URL:http://127.0.0.1/aaatest.html
    
    - proxy_set_header  Host  $host;  作用web服务器上有多个站点时,用该参数header来区分反向代理哪个域名。比如下边的代码举例。
    - proxy_set_header X-Forwarded-For  $remote_addr; 作用是后端服务器上的程序获取访客真实IP,从该header头获取。部分程序需要该功能。
    
    - Proxy_pass配合upstream实现负载均衡
    http {
        include       mime.types;
        default_type  application/octet-stream;
        sendfile        on;
     
        upstream core_tomcat {
          server 192.168.1.253:80      weight=5  max_fails=3 fail_timeout=30;
          server 192.168.1.252:80      weight=1  max_fails=3 fail_timeout=30;
          server 192.168.1.251:80      backup;
        }
    
        server {
            listen       80;
            server_name  www.jd.com;
            location /web {
                proxy_pass http://core_tomcat;
                proxy_set_header  Host  $host;
            }
        }
     }
    

    Nginx负载均衡的几种模式

    • 轮询:每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,就不在分配;
    upstream core_tomcat {
        server 192.168.1.253:80      max_fails=3 fail_timeout=30;
        server 192.168.1.252:80      max_fails=3 fail_timeout=30;
     }
    • 权重轮询:根据后端服务器性能不通配置轮询的权重比,权重越高访问的比重越高;
    upstream core_tomcat {
        server 192.168.1.253:80      weight=2  max_fails=3 fail_timeout=30;
        server 192.168.1.252:80      weight=8  max_fails=3 fail_timeout=30;
    }
    #假如有十个请求,八个会指向第二台服务器,两个指向第一台;
    
    • IP_Hash:根据请求的ip地址hash结果进行分配,第一次分配到A服务器,后面再请求默认还是分配到A服务器;可以解决Session失效重新登录问题;
    upstream core_tomcat {
      ip_hash;
      server 192.168.1.253:80      max_fails=3 fail_timeout=30;
      server 192.168.1.252:80      max_fails=3 fail_timeout=30;
    }
    • Fair:按后端服务器的响应时间来分配请求,响应时间短的优先分配;
    upstream core_tomcat {
      fair;
      server 192.168.1.253:80      max_fails=3 fail_timeout=30;
      server 192.168.1.252:80      max_fails=3 fail_timeout=30;
    }
    
    • Url_hash:按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效;

    ginx的rewrite模块指令

    Nginx的rewrite模块即ngx_http_rewrite_module标准模块,主要功能是重写请求URI,也是Nginx默认安装的模块。rewrite模块会根据PCRE正则匹配重写URI,然后根据指令参数或者发起内部跳转再一次进行location匹配,或者直接进行30x重定向返回客户端。

    rewrite模块的指令就是一门微型的编程语言,包含set、rewrite、break、if、return等一系列指令。

    set指令

    set指令是由ngx_http_rewrite_module标准模块提供的,用于向变量存放值。在Nginx配置文件中,变量只能存放一种类型的值,因为只存在一种类型的值,那就是字符串。

    set指令的配置项格式如下:

    set $variable value;

    注意:在Nginx配置文件中,变量定义和使用都要以$开头。Nginx变量名前面有一个$符号,这是记法上的要求。所有的Nginx变量在引用时必须带上$前缀。另外,Nginx变量不能与Nginx服务器预设的全局变量同名。比如,我们的nginx.conf文件中有下面这一行配置:

    set $a "hello world";

    上面的语句中,set配置指令对变量$a进行了赋值操作,把字符串hello world赋给了它。也可以直接把变量嵌入字符串常量中以构造出新的字符串:

    set $a "foo";
    set $b "$a, $a";

    这个例子通过前面定义的变量$a的值来构造变量$b的值,于是这两条指令顺序执行完之后,$a的值是"foo",而$b的值则是"foo,foo"。把变量嵌入字符串常量中以构造出新的字符串,这种技术在Linux Shell脚本中常常用到,并且被称为“变量插值”(VariableInterpolation)。

    set指令不仅有赋值的功能,还有创建Nginx变量的副作用,即当作为赋值对象的变量尚不存在时,它会自动创建该变量。比如在上面这个例子中,若$a这个变量尚未创建,则set指令会自动创建$a这个用户变量。

    Nginx变量一旦创建,其变量名的可见范围就是整个Nginx配置,甚至可以跨越不同虚拟主机的server配置块。但是,对于每个请求,所有变量都有一份独立的副本,或者说都有各变量用来存放值的容器的独立副本,彼此互不干扰。Nginx变量的生命期是不可能跨越请求边界的。

    rewrite指令

    rewrite指令是由ngx_http_rewrite_module标准模块提供的,主要功能是改写请求URI。rewrite指令的格式如下:

    rewrite regrex replacement [flag];

    如果regrex匹配URI,URI就会被替换成replacement的计算结果,replacement一般是一个“变量插值”表达式,其计算之后的字符串就是新的URI。

    下面的例子有两个重新配置项,具体如下:

    location /download/ {
     rewrite ^/download/(.*)/video/(.*)$ /view/$1/mp3/$2.mp3 last;
     rewrite ^/download/(.*)/audio/(.*)*$ /view/$1/mp3/$2.rmvb last;
     return 404;
    }
    location /view {
     echo "uri: $uri ";
    }

    在浏览器中请求http://crazydemo.com/download/1/video/10,地址发生了重写,并且发生了location的跳转,结果如图7-17所示。

    图7-17 输出结果

    在这个演示例子中,replacement中的占位变量、的值是指令参数regrex正则表达式从原始URI中匹配出来的子字符串,也叫正则捕获组,编号从1开始。

    rewrite指令可以使用的上下文为:server、location、if inlocation。

    如果rewrite同一个上下文中有多个这样的rewrite重新指令,匹配就会依照rewrite指令出现的顺序先后依次进行下去,匹配成功之后并不会终止,而是继续往下匹配,直到返回最后一个匹配的为止。如果想要中途中止,不再继续往下匹配,可以使用第3个指令参数flag。flag参数的值有last、break、redirect、permanent。

    如果flag参数使用last值,并且匹配成功,那么停止处理任何rewrite相关的指令,立即用计算后的新URI开始下一轮的location匹配和跳转。前面的例子使用的就是last参数值。

    如果flag参数使用break值,就如同break指令的字面意思一样,停止处理任何rewrite的相关指令,但是不进行location跳转。

    将上面的rewrite例子中的last参数值改成break,代码如下:

    location /view {
     echo " view : $uri ";
     }
    location /download_break/ {
     rewrite ^/download_break/(.*)/video/(.*)$ /view/$1/mp3/$2.mp3 break;
     rewrite ^/download_break/(.*)/audio/(.*)*$ /view/$1/mp3/$2.rmvb break;
     echo " download_break new uri : $uri ";
    }

    在浏览器中请求http://crazydemo.com/download_break/1/video/10,地址发生了重写,但是location并没有跳转,而是直接结束了,结果如图7-18所示。

    图7-18 显示结果

    在location上下文中,last和break是有区别的:last其实就相当于一个新的URL,Nginx进行了一次新的location匹配,通过last获得一个可以转到其他location配置中处理的机会(内部的重定向);而break在一个location中将原来的URL(包括URI和args)改写之后,再继续进行后面的处理,这个重写之后的请求始终都是在同一个location上下文中,并没有发生内部跳转。

    这里要注意:last和break的区别仅仅发生在location上下文中;如果发生在server上下文,那么last和break的作用是一样的。

    还要注意:在location上下文中的rewrite指令使用last指令参数会再次以新的URI重新发起内部重定向,再次进行location匹配,而新的URI极有可能和旧的URI一样再次匹配到相同的目标location中,这样死循环就发生了。当循环到第10次时,Nginx会终止这样无意义的循环并返回500错误。这一点需要特别注意。

    如果rewrite指令使用的flag参数的值是permanent,就表示进行外部重定向,也就是在客户端进行重定向。此时,服务器将新URI地址返回给客户端浏览器,并且返回301(永久重定向的响应码)给客户端。客户端将使用新的重定向地址再发起一次远程请求。

    永久重定向permanent的使用示例如下:

     #rewrite指令permanent参数演示
     location /download_permanent/ {
     rewrite ^/download_permanent/(.*)/video/(.*)$ /view/$1/mp3/$2.mp3 permanent;
     rewrite ^/download_permanent/(.*)/audio/(.*)*$ /view/$1/mp3/$2.rmvb permanent; return 404;
    }

    在浏览器中请求http://crazydemo.com/download_permanent/1/video/10,输出的结果如图7-19所示。

    图7-19 输出的结果

    从以上结果可以看出,永久重定向有两个比较大的特点:

    (1)浏览器的地址栏地址变成了重定向地址

    http://crazydemo.com/view/1/mp3/10.mp3。

    (2)从Fiddler抓包工具可以看到,第一个请求地址的响应状态码为301,如图7-20所示。

    图7-20 永久重定向的响应码示意图

    外部重定向与内部重定向是有本质区别的。从数量上说,外部重定向有两次请求,内部重定向只有一次请求。通过上面的几个示例,大家应该体会得相当深刻了。

    如果rewrite指令使用的flag参数的值是redirect,就表示进行外部重定向,表现的行为与permanent参数值完全一样,不同的是返回302(临时重定向的响应码)给客户端。

    有关redirect参数值的实例这里不进行演示,大家可自行下载和运行本文的源码并细细体会。

    rewrite能够利用正则捕获组设置变量,作为实验,我们可以在Nginx的配置文件中加入这么一条location规则:

    location /capture_demo {
     rewrite ^/capture_demo/(.*)/video/(.*)$ /view/$1/mp3/$2.mp3 break;
     rewrite ^/capture_demo/(.*)/audio/(.*)*$ /view/$1/mp3/$2.rmvb break;
    捕获组
    捕获组 echo " 捕获组1:$1;捕获组2:$2";
    }

    在浏览器中请求http://crazydemo.com/capture_demo/group1/video/group2,输出的结果如图7-21所示。

    图7-21 输出的结果

    if条件指令

    if条件指令配置项的格式如下:

    if (condition) {...}

    当if条件满足时,执行配置块中的配置指令。if的配置块相当于引入了一个新的上下文作用域。if条件指令适用于server和location两个上下文。

    condition条件表达式可以用到一系列比较操作符,大致如下:

    (1)==:相等。

    (2)!=:不相等。

    (3)~:区分字母大小写模式匹配。

    (4)~*:不区分字母大小写模式匹配。

    (5)还有其他几个专用比较符号,比如判断文件及目录是否存在的符号,等等。

    下面是一个简单的演示程序,根据内置变量$http_user_agent的值判断客户端的类型,代码如下:

    #if指令的演示程序
    location /if_demo {
     if ($http_user_agent ~*"Firefox") { #匹配Firefox浏览器
     return 403;
     }

    匹配谷歌浏览器

     if ($http_user_agent ~*"Chrome") { #匹配Chrome谷歌浏览器
     return 301;
     }
     if ($http_user_agent ~*"iphone") { #匹配iPhone手机
     return 302;
     }
     if ($http_user_agent ~*"android") { #匹配安卓手机
     return 404;
     }
     return 405; #其他浏览器默认访问规则
    }

    在火狐浏览器中访问http://crazydemo.com/if_demo,结果如图7-22所示。

    图7-22 火狐浏览器的访问结果

    在谷歌浏览器中访问http://crazydemo.com/if_demo,结果如图7-23所示。

    图7-23 谷歌浏览器的访问结果

    在演示代码中使用到了return指令,用于返回HTTP的状态码。

    return指令会停止同一个作用域的剩余指令处理,并返回给客户端指定的响应码。

    return指令可以用于server、location、if上下文中,执行阶段是rewrite阶段。其指令的格式如下:

    #格式一:返回响应的状态码和提示文字,提示文字可选
    return code [text];
    #格式二:返回响应的重定向状态码(如301)和重定向URL
    return code URL;
    #格式三:返回响应的重定向URL,默认的返回状态码是临时重定向302
    return URL;

    add_header指令

    response header一般是以key:value的形式,例如Content-Encoding:

    gzip、Cache-Control:no-store,设置的命令如下:

    add_header Cache-Control no-store
    add_header Content-Encoding gzip

    但是,有一个十分常用的response header为Content-Type,可以在它设置了类型的同时指定charset,例如text/html;charset=utf-8,由于其存在分号,而分号在配置文件中作为结束符,因此在配置时需要用引号把其引起来,配置如下:

    add_header Content-Type 'text/html; charset=utf-8';

    另外,由于没有单独设置charset的key,因此要设置响应的charset就需要使用Content-Type来指定charset。

    使用AJAX进行跨域请求时,浏览器会向跨域资源的服务端发送一个OPTIONS请求,用于判断实际请求是否安全或者判断服务端是否允许跨域访问,这种请求也叫作预检请求。跨域访问的预检请求是浏览器自动发出的,用户程序往往不知情,如果不进行特别的配置,那么客户端发出一次请求,在服务端往往会收到两个请求;一个是预检请求;另一个是正式的请求。后端的服务器(PHP或者Tomcat)如果不经过特殊的过滤,那么很容易将OPTIONS预检请求当成正式的数据请求。

    对于客户端而言,只有预检请求返回成功,客户端才开始正式请求。在实际的使用场景中,预检请求比较影响性能,用户往往会有两倍请求的感觉,所以一般会在Nginx代理服务端对预检请求进行提前拦截,同时对预检请求设置比较长时间的有效期。

    upstream zuul {
     #server 192.168.233.1:7799;
     server "192.168.233.128:7799";
     keepalive 1000;
     }
     server {
     listen 80;
     server_name nginx.server *.nginx.server;
     default_type 'text/html';
     charset utf-8;
     #转发到上游服务器,但是 'OPTIONS' 请求直接返回空
     location / {
     if ($request_method='OPTIONS') {
     add_header Access-Control-Max-Age 1728000;
     add_header Access-Control-Allow-Origin *;
     add_header Access-Control-Allow-Credentials true;
     add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
     add_header Access-Control-Allow-Headers 'Keep-Alive,User-Agent,X-Requested-With,\
    If-Modified-Since,Cache-Control,Content-Type,token';
     return 204;
     }
     proxy_pass http://zuul/ ;
     }
     }

    配置Nginx,加入Access-Control-Max-Age请求头,用来指定本次预检请求的有效期,单位为秒。上面结果中的有效期是20天(1 728 000秒),即允许缓存该条回应1 728 000秒,在此期间客户端不用发出另一条预检请求。

    指令的执行顺序

    大多数Nginx新手都会频繁遇到这样一个困惑:当同一个location配置块使用了多个Nginx模块的配置指令时,这些指令的执行顺序很可能会跟它们的书写顺序大相径庭。现在就来看这样一个令人困惑的例子:

    location /sequence_demo_1 {
     set $a foo;
     echo $a;
     set $a bar;
     echo $a;
    }

    上面的代码先给变量$a赋值foo,随后输出,再给变量$a赋值bar,随后输出。如果这是一段Java代码,毫无疑问,最终的输出结果一定为“foo bar”。然而不幸的是,事实并非如此,在浏览器中访问http://crazydemo.com/sequence_demo_1,结果如图7-24所示。

    图7-24 输出的结果

    为什么出现了这种不合常理的现象呢?

    前面讲到,Nginx的请求处理阶段共有11个,分别是post-read、server-rewrite、find-config、rewrite、post-rewrite、preaccess、access、post-access、try-files、content以及log。其中3个比较常见的按照执行时的先后顺序依次是rewrite阶段、access阶段以及content阶段。

    Nginx的配置指令一般只会注册并运行在其中的某一个处理阶段,比如set指令就是在rewrite阶段运行的,而echo指令只会在content阶段运行。在一次请求处理流程中,rewrite阶段总是在content阶段之前执行。因此,属于rewrite阶段的配置指令(示例中的set)总是会无条件地在content阶段的配置指令(示例中的echo)之前执行,即便是echo配置项出现在set配置项的前面。

    上面例子中的指令按照请求处理阶段的先后次序排序,实际的执行次序如下:

    location /sequence_demo_1 {
     #rewrite阶段的配置指令,执行在前面
     set $a foo;
     set $a bar;
     #content阶段的配置指令,执行在后面
     echo $a;
     echo $a;
    }

    所以,输出的结果就是bar bar了。

    本文给大家讲解的内容是Nginx/OpenResty详解,Nginx的rewrite模块指令

    1. 下篇文章给大家讲解的是 Nginx/OpenResty详解,反向代理与负载均衡配置;
    2. 觉得文章不错的朋友可以转发此文关注小编;
    3. 感谢大家的支持!