也有一些变量是支持改写的,其中一个例子是$args.这个变量在读取时返回当前请求的URL参数串(即请求URL中问好后面的部分,如果有的话),而在赋值时可以直接修改参数串。我们来看一个例子:
location /test {
set $orig_args $args;
set $args "a=3&b=4";
echo "original1 args: $orig_args";
echo "args: $args";
}
这里我们把原始的URL参数串先保存在$orig_args 变量中,然后通过改写$args变量来修改当前的URL参数串,最后我们用echo指令分别输出$orig_args和$args变量的值。接下来我们这样来测试这个/test接口:
$ curl 'http://localhost:8080/test'
original args:
args: a=3&b=4
$curl 'http://localhost:8080/test?a=0&b=1&c=2'
original args: a=0&b=1&c=2
args:a=3&b=4
在第一次测试中,我们没有设置任何URL参数串,所以输出$orig_args变量的值时便得到空。而在第一次和第二次测试中,无论我们是否提供URL参数串,参数串都会在location /test中被强行改写成a=3&b=4.
需要特备指出的时,这里的$args变量和$arg_xxx一样,也不再使用属于自己的存放值的容器。当我们读取$args时,nginx会执行一小段代码,从nginx核心中专门存放当前UR了参数串的位置去读取数据;当我们改写$args时,nginx会执行另一小段代码,对相同位置进行改写。nginx的其他部分在需要当前URL参数串的时候,都会从那个位置去读数据,所以我们对$args的修改会影响到所有部分的功能。我们来看一段例子:
location ./test{
set $orig_a $arg_a;
set $args "a=5";
echo :"original a :$orig_a";
echo :"a: $arg_a":
}
$curl 'http://localhost:8080/test?a=3'
original a:3
a : 5
我们看到,因为原始请求的URL参数串时a=3,所以$arg_a最初的值为3,但随后通过改写$args变量,将URL参数串又强行修改为a=5,所以最终$arg_a的值又自动变味了5.
我们再来看一个通过修改$args变量影响标准的HTTP代理模块ngx_proxy的例子:
server {
listen 8080;
location /test {
set $args "foo=1&bar=2";
proxy_pass http://127.0.0.1:8080/args;
}
}
server {
listen 8081;
location /args {
echo "args:$args";
}
}
这里我们在http配置块中定义了两个虚拟主机。第一个虚拟主机监听8080端口,其/test接口自己通过改写$args变量,将当前请求的URL参数串无条件的修改为foo=1&bar=2.然后/test接口在通过ngx_proxy模块的proxy_pass指令配置了一个方向代理,指向本机的8081端口上的HTTP服务/args默认情况下,ngx_proxy 模块在转发HTTP请求带远方的HTTP服务的时候,会自动把当前请求的URL参数串也转发到远方。