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

原文地址:https://www.cnblogs.com/liqiu/p/2946948.html