Nginx 变量漫谈(二)
来源:互联网 发布:美股港股实时行情软件 编辑:程序博客网 时间:2024/05/01 07:44
location
配置块绑定的。其实不然。我们来看一个涉及“内部跳转”的例子:
server { listen 8080; location /foo { set $a hello; echo_exec /bar; } location /bar { echo "a = ;[$a]" } }
这里我们在 location /foo
中,使用第三方模块 ngx_echo 提供的 echo_exec 配置指令,发起到 location /bar
的“内部跳转”。所谓“内部跳转”,就是在处理请求的过程中,于服务器内部,从一个location
跳转到另一个 location
的过程。这不同于利用 HTTP 状态码 301
和302
所进行的“外部跳转”,因为后者是由 HTTP 客户端配合进行跳转的,而且在客户端,用户可以通过浏览器地址栏这样的界面,看到请求的 URL 地址发生了变化。内部跳转和Bourne Shell
(或 Bash
)中的 exec
命令很像,都是“有去无回”。另一个相近的例子是C
语言中的 goto
语句。
location
发生了变化,所以还是原来的那一套 Nginx 变量的容器副本。对应到上例,如果我们请求的是/foo
这个接口,那么整个工作流程是这样的:先在 location /foo
中通过 set 指令将 $a
变量的值赋为字符串 hello
,然后通过 echo_exec 指令发起内部跳转,又进入到 location /bar
中,再输出 $a
变量的值。因为$a
还是原来的 $a
,所以我们可以期望得到 hello
这行输出。测试证实了这一点:
$ curl localhost:8080/foo a = [hello]
但如果我们从客户端直接访问 /bar
接口,就会得到空的 $a
变量的值,因为它依赖于 location /foo
来对$a
进行初始化。
location
配置块,它使用的还是同一套 Nginx 变量的副本。这里,我们也首次涉及到了“内部跳转”这个概念。值得一提的是,标准ngx_rewrite 模块的rewrite 配置指令其实也可以发起“内部跳转”,例如上面那个例子用 rewrite 配置指令可以改写成下面这样的形式:
server { listen 8080; location /foo { set $a hello; rewrite ^ /bar; } location /bar { echo "a = ;[$a]" } }
其效果和使用 echo_exec 是完全相同的。后面我们还会专门介绍这个 rewrite 指令的更多用法,比如发起 301
和 302
这样的“外部跳转”。
location
无关。
location /test { echo "uri = ;$uri" echo "request_uri = ;$request_uri" }
这里为了简单起见,连 server
配置块也省略了,和前面所有示例一样,我们监听的依然是 8080
端口。在这个例子里,我们把$uri 和$request_uri 的值输出到响应体中去。下面我们用不同的请求来测试一下这个 /test
接口:
$ curl 'http://localhost:8080/test' uri = /test request_uri = /test $ curl 'http://localhost:8080/test?a=3&b=4' uri = /test request_uri = /test?a=3&b=4 $ curl 'http://localhost:8080/test/hello%20world?a=3&b=4' uri = /test/hello world request_uri = /test/hello%20world?a=3&b=4
另一个特别常用的内建变量其实并不是单独一个变量,而是有无限多变种的一群变量,即名字以 arg_
开头的所有变量,我们估且称之为 $arg_XXX 变量群。一个例子是 $arg_name
,这个变量的值是当前请求名为 name
的 URI 参数的值,而且还是未解码的原始形式的值。我们来看一个比较完整的示例:
location /test { echo "name: $arg_name" ;echo "class: $arg_class" ;}
然后在命令行上使用各种参数组合去请求这个 /test
接口:
$ curl 'http://localhost:8080/test' name: class: $ curl 'http://localhost:8080/test?name=Tom&class=3' name: Tom class: 3 $ curl 'http://localhost:8080/test?name=hello%20world&class=9' name: hello%20world class: 9
其实 $arg_name
不仅可以匹配 name
参数,也可以匹配 NAME
参数,抑或是Name
,等等:
$ curl 'http://localhost:8080/test?NAME=Marry' name: Marry class: $ curl 'http://localhost:8080/test?Name=Jimmy' name: Jimmy class:
Nginx 会在匹配参数名之前,自动把原始请求中的参数名调整为全部小写的形式。
%XX
这样的编码序列进行解码,可以使用第三方 ngx_set_misc 模块提供的 set_unescape_uri 配置指令:
location /test { set_unescape_uri $name $arg_name; set_unescape_uri $class $arg_class; echo "name: $name" ;echo "class: $class" ;}
现在我们再看一下效果:
$ curl 'http://localhost:8080/test?name=hello%20world&class=9' name: hello world class: 9
空格果然被解码出来了!
? location /bad { ? set $uri /blah; ? echo $uri; ? }
这个有问题的配置会让 Nginx 在启动的时候报出一条令人匪夷所思的错误:
[emerg] the duplicate "uri" variable in ...
如果你尝试改写另外一些只读的内建变量,比如 $arg_XXX 变量,在某些 Nginx 的版本中甚至可能导致进程崩溃。
- Nginx 变量漫谈(二)
- Nginx 变量漫谈(一)
- Nginx 变量漫谈(三)
- Nginx 变量漫谈(四)
- Nginx 变量漫谈(五)
- Nginx 变量漫谈(六)
- Nginx 变量漫谈(七)
- Nginx 变量漫谈(八)
- Nginx 变量漫谈(三)
- Nginx 变量漫谈(一)(转)
- 再谈nginx变量(二)
- Lucene漫谈(二)
- 漫谈-----泛型(二)
- 递归漫谈(二)
- 漫谈LCD调试(二)
- 【Windows】线程漫谈(二)
- 数据可视化漫谈(二)
- 漫谈继承技术(二)
- POI读取EXCEL教程
- C++十四周任务-数组大折腾
- 在ADF中使用AutoSuggest
- cookie的path和domain属性解析
- C#中抽象类和接口的区别
- Nginx 变量漫谈(二)
- 配置MSVC命令行环境
- 只能输入数字的方法
- ORACLE EM此网站的安全证书有问题
- 自动人脸识别基本原理
- Nginx 变量漫谈(三)
- Struts和Spring 实现mvc的比较
- MFC中几种获取视图指针方法
- 【转】IE 无法使用 js trim() 的解决方法