XXX
的 cookie 不存在时返回特殊值“没找到”:
location /test { content_by_lua ' if ngx.var.cookie_user == nil then ngx.say("cookie user: missing") else ngx.say("cookie user: [", ngx.var.cookie_user, "]") end '; }
利用 curl
命令行工具的 --cookie name=value
选项可以指定 name=value
为当前请求携带的 cookie(通过添加相应的Cookie
请求头)。下面是若干次测试结果:
$ curl --cookie user=agentzh 'http://localhost:8080/test' cookie user: [agentzh] $ curl --cookie user= 'http://localhost:8080/test' cookie user: [] $ curl 'http://localhost:8080/test' cookie user: missing
我们看到,cookie user
不存在以及取值为空字符串这两种情况被很好地区分开了:当 cookie user
不存在时,Lua 代码中的ngx.var.cookie_user
返回了期望的 Lua nil
值。
nil
值,而不会像先前的例子那样直接让 Nginx 拒绝加载配置:
location /test { content_by_lua ' ngx.say("$blah = ", ngx.var.blah) '; }
这里假设我们并没有在当前的 nginx.conf
配置文件中创建过用户变量 $blah
,然后我们在 Lua 代码中通过ngx.var.blah
直接引用它。上面这个配置可以顺利启动,因为 Nginx 在加载配置时只会编译 content_by_lua 配置指令指定的 Lua 代码而不会实际执行它,所以 Nginx 并不知道 Lua 代码里面引用了 $blah
这个变量。于是我们在运行时也会得到nil
值。而 ngx_lua 提供的 ngx.say 函数会自动把 Lua 的 nil
值格式化为字符串 "nil"
输出,于是访问 /test
接口的结果是:
curl 'http://localhost:8080/test' $blah = nil
这正是我们所期望的。
$bar
符号,但却并没有触发“变量插值”(否则 Nginx 会在启动时抱怨$blah
未创建)。这是因为 content_by_lua 配置指令并不支持参数的“变量插值”功能。我们前面在 (一) 中提到过,配置指令的参数是否允许“变量插值”,其实取决于该指令的实现模块。
location /foo { content_by_lua ' if ngx.var.foo == nil then ngx.say("$foo is nil") else ngx.say("$foo = [", ngx.var.foo, "]") end '; } location /bar { set $foo 32; echo "foo = [$foo]"; }
请求 /foo
接口的结果是:
$ curl 'http://localhost:8080/foo' $foo = []
我们看到在 Lua 里面读取未初始化的 Nginx 变量 $foo
时得到的是空字符串。
location /test { array_split "," $arg_names to=$array; array_map "[$array_it]" $array; array_join " " $array to=$res; echo $res; }
这个例子中使用了 ngx_array_var 模块的 array_split
、 array_map
和 array_join
这三条配置指令,其含义很接近 Perl 语言中的内建函数split
、map
和 join
(当然,其他脚本语言也有类似的等价物)。我们来看看访问/test
接口的结果:
$ curl 'http://localhost:8080/test?names=Tom,Jim,Bob [Tom] [Jim] [Bob]
我们看到,使用 ngx_array_var 模块可以很方便地处理这样具有不定个数的组成元素的输入数据,例如此例中的 names
URL 参数值就是由不定个数的逗号分隔的名字所组成。不过,这种类型的复杂任务通过ngx_lua 来做通常会更灵活而且更容易维护。