HttpLuaModule——翻译(7.10 ngx.location.capture)
已经更新到官方文档:http://wiki.nginx.org/HttpLuaModule#
ngx.location.capture
语法: res = ngx.location.capture(uri, options?)
环境: rewrite_by_lua*, access_by_lua*, content_by_lua*
是一个同步非阻塞的NGINX子请求uri
NGINX的子请求提供了一个非常强大的方式去实现非阻塞的内部请求,或者其他的C模块,比如 ngx_proxy, ngx_fastcgi, ngx_memc, ngx_postgres, ngx_drizzle, 甚至ngx_lua自己等等。
当然,这些子请求仅仅是模拟HTTP请求,但是并没有额外的 HTTP/TCP,所有的进程都是C级别的
子请求完全不同与HTTP 301/302。
这里有个基本的例子:
res = ngx.location.capture(uri)
返回一个LUA的TABLE,三个值(res.status, res.header, and res.body)。
res.header包含了所有的子请求的头的信息,它是一个普通的LUA TABLE。比如多个值的相应头,他们以数组的形式按照顺序返回出现。例如:子请求包含了如下信息:
Set-Cookie: a=3 Set-Cookie: foo=bar Set-Cookie: baz=blah
如上,res.header["Set-Cookie"] = {"a=3", "foo=bar", "baz=blah"}
URI也可以链接自己,例如:
res = ngx.location.capture('/foo/bar?a=3&b=4')
capture函数的第二个参数是可选的,详细说明如下
method: 请求方式,比如ngx.HTTP_POST
body: 子请求的内容
args: 参数
ctx: 特殊的ngx.ctx变量,可以被当前请求赋值,也可以在子请求使用,父子请求共享的变量
vars
copy_all_vars
share_all_vars
POST事例
res = ngx.location.capture( '/foo/bar', { method = ngx.HTTP_POST, body = 'hello, world' } )
默认是HTTP_GET
args实例
ngx.location.capture('/foo?a=1', { args = { b = 3, c = ':' } } )
相同于
ngx.location.capture('/foo?a=1&b=3&c=%3a')
share_all_vars控制着当前请求是否与子请求分享变量,默认情况是false。如果分享,在子请求修改变量,父请求的变量也随着修改。
location /other { set $dog "$dog world"; echo "$uri dog: $dog"; } location /lua { set $dog 'hello'; content_by_lua ' res = ngx.location.capture("/other", { share_all_vars = true }); ngx.print(res.body) ngx.say(ngx.var.uri, ": ", ngx.var.dog) '; }
请求 /lua
/other dog: hello world
/lua: hello world
copy_all_vars,顾名思义,就是拷贝父请求的变量到子请求,当子请求变量修改的时候不影响到父请求
location /other { set $dog "$dog world"; echo "$uri dog: $dog"; } location /lua { set $dog 'hello'; content_by_lua ' res = ngx.location.capture("/other", { copy_all_vars = true }); ngx.print(res.body) ngx.say(ngx.var.uri, ": ", ngx.var.dog) '; }
请求 /lua
/other dog: hello world
/lua: hello
有人可能会问,如果copy_all_vars和share_all_vars同时设置成为true,将会怎样?答:share_all_vars启作用。
当然还有一种情况,当前请求给变量赋值,而在vars里同样也给变量赋值,结果是vars里面的
location /other { content_by_lua ' ngx.say("dog = ", ngx.var.dog) ngx.say("cat = ", ngx.var.cat) '; } location /lua { set $dog ''; set $cat ''; content_by_lua ' res = ngx.location.capture("/other", { vars = { dog = "hello", cat = 32 }}); ngx.print(res.body) '; } 请求/lua 输出 dog = hello cat = 32
变量也可以被ctx共享
location /sub { content_by_lua ' ngx.ctx.foo = "bar"; '; } location /lua { content_by_lua ' res = ngx.location.capture("/sub", { ctx = ngx.ctx }) ngx.say(ngx.ctx.foo); '; }
请求 /lua
输出
bar
location /sub { content_by_lua ' ngx.ctx.foo = "bar"; '; } location /lua { content_by_lua ' local ctx = {} res = ngx.location.capture("/sub", { ctx = ctx }) ngx.say(ctx.foo); ngx.say(ngx.ctx.foo); '; } 请求 /lua 输出 bar nil
FROM http://wiki.nginx.org/HttpLuaModule#ngx.location.capture