已經更新到官方文檔: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