Nginx Lua 三種重定向的使用及比較


#lua 三種重定向的使用及比較

1. ngx.exec
語法:ngx.exec(uri, args?)
主要實現的是內部的重定向,等價於下面的rewrite指令:

rewrite regrex replacement last;

  例子:

ngx.exec('/some-location');
ngx.exec('/some-location', 'a=3&b=5&c=6');
ngx.exec('/some-location?a=3&b=5', 'c=6');

args參數可以以string的形式給出,也可以以lua table的形式給出,如下所示:

location /foo {
content_by_lua_block {
ngx.exec("/bar", { a= 4, b="hello world"});
}
}

location /bar {
content_by_lua_block {
local args = ngx.req.get_uri_args()
for key, val in pairs(args) do
ngx.say(key.." = "..val)
end
}
}

如果給定的uri是命名的location,那么可選參數args就會被自動忽略的,如下所示:

"GET /foo/file.php?a=hello" 請求將返回hello 而不是goodbye

```
location /foo {
content_by_lua_block {
ngx.exec("@bar", "a=goodbye");
}
}

location @bar {
content_by_lua_block {
local args = ngx.req.get_uri_args()
for key, val in pairs(args) do
if key == "a" then
ngx.say(val)
end
end
}
}
```

該方法不會主動返回,因此,強烈建議在調用該方法時,最好顯示加上return,如下所示:

return ngx.exec(...)

2. ngx.redirect
語法:ngx.redirect(uri, status?)
該方法會給客戶端返回一個301/302重定向,具體是301還是302取決於設定的status值。

如果不指定status值,默認是返回302 (ngx.HTTP_MOVED_TEMPORARILY),其等價於下面的rewrite指令:

rewrite ^ /foo? permanent;# nginx config

如果返回301,那么等價於下面的rewrite指令:

rewrite ^ /foo? redirect;# nginx config

該方法不會主動返回,因此,強烈建議在調用該方法時,最好顯示加上return,如下所示:

return ngx.redirect('/foo?a=3&b=4')

3. ngx.location.capture
語法: res= ngx.location.capture(uri, options?)

  用於發出一個同步的,非阻塞的Nginx subrequest(子請求)。
  Nginx 子請求可以向其它location發出非阻塞的內部請求,這些location可以是配置用於讀取文件夾的,也可以是其它的C模塊,比如ngx_proxy, ngx_fastcgi, ngx_memc, ngx_postgres, ngx_drizzle甚至是ngx_lua自己。

  Subrequest只是模擬Http接口,並沒有額外的Http或者Tcp傳輸開銷,它在C層次上運行,非常高效。Subrequest不同於Http 301/302重定向,以及外部重定向(通過ngx.redirect)和內部重定向(通過ngx.exec)。

下面是一個基本的例子:

res = ngx.location.capture(uri)

  返回一個LUA的TABLE,四個值(res.status, res.header, res.body, and res.truncated)。

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')

  需要注意的是命名的locations,比如@foo在nginx core是不被允許的。

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' }
)

args事例:

ngx.location.capture('/foo?a=1',
{ args = { b = 3, c = ':' } }
)

 

copy_all_vars: 顧名思義,就是拷貝父請求的變量到子請求,當子請求變量修改的時候不影響到父請求.

location /other {
set $dog "$dog world";
echo "$uri dog: $dog";
}

location /lua {
set $dog 'hello';
content_by_lua_block {
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

share_all_vars: 控制着當前請求是否與子請求分享變量,默認情況是false。如果分享,在子請求修改變量,父請求的變量也隨着修改,默認情況下是關閉狀態。

location /other {
set $dog "$dog world";
echo "$uri dog: $dog";
}

location /lua {
set $dog 'hello';
content_by_lua_block {
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

文章參考:

http://blog.csdn.net/chosen0ne/article/details/7304192
https://github.com/openresty/lua-nginx-module#ngxlocationcapture

原文鏈接:https://blog.csdn.net/liwf616/java/article/details/78256062


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM