curl --location --request POST 'http://localhost:8081/ngx_vars?a=1&b=2' \
--header 'Content-Type: application/json' \
--header 'request_id: aabbcc' \
--header 'Authorization: Basic Og==' \
--data-raw '{"hello": "world"}'
ngx.req.read_body() -- 读取body
ngx.say("==========print nginx var begin=============\n")
ngx.say("$request => ", ngx.var.request, "\n")
ngx.say("$content_type => ", ngx.var.content_type, "\n")
ngx.say("$request_method => ", ngx.var.request_method)
ngx.say("$uri => ", ngx.var.uri)
ngx.say("$is_args => ", ngx.var.is_args)
ngx.say("$args => ", ngx.var.args)
ngx.say("$query_string => ", ngx.var.query_string)
ngx.say("$request_uri => ", ngx.var.request_uri)
ngx.say("$request_body => ", ngx.var.request_body, "\n")
ngx.say("$document_root => ", ngx.var.document_root)
ngx.say("$document_uri => ", ngx.var.document_uri)
ngx.say("$request_filename => ", ngx.var.request_filename, "\n")
ngx.say("$server_name => ", ngx.var.server_name)
ngx.say("$server_addr => ", ngx.var.server_addr)
ngx.say("$server_port => ", ngx.var.server_port, "\n")
ngx.say("$remote_addr => ", ngx.var.remote_addr)
ngx.say("$remote_port => ", ngx.var.remote_port, "\n")
ngx.say("==========print nginx var end=============\n")
ngx.say("==========print nginx header begin=============\n")
local headers = ngx.req.get_headers()
for k, v in pairs(headers) do
if type(v) == "table" then
ngx.say(k..": "..table.concat(v, ",").."\n")
else
ngx.say(k..": "..v.."\n")
end
end
ngx.say("==========print nginx header end=============\n")
ngx.say("==========print nginx uri_args begin=============\n")
local uri_args = ngx.req.get_uri_args()
for k, v in pairs(uri_args) do
if type(v) == "table" then
ngx.say(k..": "..table.concat(v, ",").."\n")
else
ngx.say(k..": "..v.."\n")
end
end
ngx.say("==========print nginx uri_args end=============")
==========print nginx var begin=============
$request => POST /ngx_vars?a=1&b=2 HTTP/1.1
$content_type => application/json
$request_method => POST
$uri => /ngx_vars
$is_args => ?
$args => a=1&b=2
$query_string => a=1&b=2
$request_uri => /ngx_vars?a=1&b=2
$request_body => {"hello": "world"}
$document_root => ./html
$document_uri => /ngx_vars
$request_filename => ./html/ngx_vars
$server_name => localhost
$server_addr => 127.0.0.1
$server_port => 8081
$remote_addr => 127.0.0.1
$remote_port => 4675
==========print nginx var end=============
==========print nginx header begin=============
host: localhost:8081
content-type: application/json
postman-token: d2b0988e-7476-47a4-97d8-7909924eeab2
accept: */*
cache-control: no-cache
content-length: 18
accept-encoding: gzip, deflate, br
user-agent: PostmanRuntime/7.24.1
connection: keep-alive
authorization: Basic Og==
==========print nginx header end=============
==========print nginx uri_args begin=============
a: 1
b: 2
==========print nginx uri_args end=============
location 比较的是
$uri
内置参数
=
优先级最高,绝对匹配^~
在正则之前匹配,普通字符串匹配~
和 ~*
正则匹配空
在正则之后匹配,普通字符串匹配,可以假想一下,空 = ~$
GET http://localhost:8081/hello?a=1
location / {
default_type text/html;
content_by_lua 'ngx.say("default route")';
}
location = /hello {
default_type text/html;
content_by_lua 'ngx.say("= /hello")';
}
location ^~ /hello {
default_type text/html;
content_by_lua 'ngx.say("^~ /hello")';
}
location ~ /hello {
default_type text/html;
content_by_lua 'ngx.say("~ /hello")';
}
#location /hello {
# default_type text/html;
# content_by_lua 'ngx.say("/hello")';
#}
1、优先匹配location = /hello
2、注销1,优先匹配location ^~ /hello
3、注销2,打开最后一个,优先匹配location ~ /hello
4、注销3,打开最后一个,优先匹配location /hello
5、找不到任何匹配项,会默认匹配location /
rewrite,重写的是
$uri
内置参数,并默认拼接上$args
POST http://localhost:8081/ngx_vars?a=1&b=2
server {
listen 8081;
server_name localhost;
location /ngx_vars {
# 注意看这里
rewrite ^/(.*)$ /hello?q=$1 last;
# 关闭lua缓存
lua_code_cache off;
default_type text/html;
content_by_lua_file conf/lua/test.lua;
}
location / {
default_type text/html;
content_by_lua 'ngx.say("default route ", ngx.var.args)';
}
location = /hello {
default_type text/html;
content_by_lua 'ngx.say("= /hello ", ngx.var.args)';
}
location ^~ /hello {
default_type text/html;
content_by_lua 'ngx.say("^~ /hello ", ngx.var.args)';
}
location ~ /hello {
default_type text/html;
content_by_lua 'ngx.say("~ /hello ", ngx.var.args)';
}
#location /hello {
# default_type text/html;
# content_by_lua 'ngx.say("/hello ", ngx.var.args)';
#}
}
= /hello q=ngx_vars&a=1&b=2
我们看到,$1匹配提取的是ngx_vars,然后重写后的路由是/hello?q=ngx_vars&a=1&b=2
$args参数的内容默认拼接到了后面,不想拼接的话,可以在后面加一个问号?
,如下
rewrite ^/(.*)$ /hello?q=$1? last;
后面的lua脚本并没有被执行,因为last
的flag
,表示重新从开头匹配location
如果是break
,则中断所有的后续匹配,执行当前的location
到最后为止。
我们看看,修改为break
以后,nginx内置参数的变化,如下:
==========print nginx var begin=============
$request => POST /ngx_vars?a=1&b=2 HTTP/1.1
$content_type => application/json
$request_method => POST
$uri => /hello
$is_args => ?
$args => q=ngx_vars&a=1&b=2
$query_string => q=ngx_vars&a=1&b=2
$request_uri => /ngx_vars?a=1&b=2
$request_body => {"hello": "world"}
$document_root => ./html
$document_uri => /hello
$request_filename => ./html/hello
$server_name => localhost
$server_addr => 127.0.0.1
$server_port => 8081
$remote_addr => 127.0.0.1
$remote_port => 6508
==========print nginx var end=============
==========print nginx header begin=============
host: localhost:8081
content-type: application/json
postman-token: ac87d63c-1d64-48f2-9f4f-b733a78de6ee
accept: */*
cache-control: no-cache
content-length: 18
accept-encoding: gzip, deflate, br
user-agent: PostmanRuntime/7.24.1
connection: keep-alive
authorization: Basic Og==
==========print nginx header end=============
==========print nginx uri_args begin=============
b: 2
q: ngx_vars
a: 1
==========print nginx uri_args end=============
由此可见,重写以后
变化的有
$uri => /hello
$args => q=ngx_vars&a=1&b=2
$query_string => q=ngx_vars&a=1&b=2
$document_uri => /hello
$request_filename => ./html/hello
没有变化的重点变量为
$request => POST /ngx_vars?a=1&b=2 HTTP/1.1
$request_uri => /ngx_vars?a=1&b=2
另外,值得一说的是break
和last
last
:立马跳出当前的location,从头开始逐个匹配新的$uri
break
:不会立马跳出location,而是默默的继续执行当前location中的其他代码,然后结束
还有2个flag
redirect
:返回302,临时重定向
permanent
:返回301,永久重定向
if
的正则表达式有如下匹配=
:等值比较~
:区分大小写,匹配~*
:不区分大小写,匹配!~
:区分大小写,不匹配!~*
:不区分大小写,不匹配if
的文件相关的判断-f
, !-f
:判断文件是否存在-d
, !-d
:判断目录是否存在-e
, !-e
:判断文件、目录或者符号链接是否存在-x
, !-x
:判断文件是否存在且可执行 location /hello {
default_type text/html;
if ($args ~* "^a=(\d)$")
{
return 401;
}
if (!-f $request_filename)
{
return 404;
}
content_by_lua 'ngx.say("= /hello ", ngx.var.args)';
}
如果参数$args
为a=数字
,就会401,文件不存在就返回404,否则打印字符串