大家好,又见面了,我是全栈君。
本篇总结来自 OpenResty(Nginx+Lua)开发入门 ,基本的代码没有改动,主要是自己实际动手操作,测试 Nginx Lua API !
我们需要接收请求、处理并输出响应。而对于请求我们需要获取如请求参数、请求头、Body体等信息;而对于处理就是调用相应的Lua代码即可;输出响应需要进行响应状态码、响应头和响应内容体的输出。因此我们从如上几个点出发即可。
接收请求
我自己进行测试,在我安装的openresty目录下的learn_lua新增一个目录,并新增一个request.lua文件
[dufy@localhost learn_lua]$ mkdir req_resp
[dufy@localhost learn_lua]$ cd req_resp
[dufy@localhost req_resp]$ touch request.lua
测试nginx变量
在 nginx.conf 中添加:
# ~ 表示 执行一个正则匹配,区分大小写
# ~* 表示 执行一个正则匹配,不区分大小写
# (\d+)/(\d+) 匹配数字 ,如 1/2 .
location ~* /lua_request/(\d+)/(\d+) {
#设置nginx变量
#$1 : 表示获取正则匹配中第一个(\d+)的值,将值赋值给 $a,$a代表一个变量
set $a $1;
#$b 是一个变量,$host 内置变量,获取主机名称
set $b $host;
#$c 是一个变量,$http_host内置变量,获取主机名称
set $c $http_host;
default_type "text/html";
#nginx使用 lua脚本进行 内容处理
content_by_lua_file /usr/example/lua/test_request.lua;
#内容体处理完成后调用
echo_after_body "ngx.var.b $b";
echo_after_body "http_host $c";
}
在 request.lua 中先添加内容
-- 1.nginx变量 # -- 在lua中代表注释
local var = ngx.var
ngx.say("ngx.var.a : ", var.a, "<br/>")
ngx.say("ngx.var.b : ", var.b, "<br/>")
ngx.say("ngx.var[2] : ", var[2], "<br/>")
ngx.var.b = 2;
ngx.say("<br/>")
测试结果如下:
ngx.var.a : 1
ngx.var.b : 192.168.1.110
ngx.var[2]20
ngx.var.b 2
c var is : 192.168.1.110:8080
[dufy@localhost req_resp]$ curl http://localhost:8080/lua_request/1/110
ngx.var.a : 1<br/>
ngx.var.b : localhost<br/>
ngx.var[2]110<br/>
<br/>
ngx.var.b 2
c var is : localhost:8080
(1):ngx.var :获取 nginx变量,如果要赋值如ngx.var.b = 2,此变量必须提前声明;
(2):另外对于nginx location中使用正则捕获的捕获组可以使用ngx.var[捕获组数字]获取;
注意:使用ngx.var获取nginx变量,获取的时候是var.a,而不是var.$a,在request_lua中虽然修改 ngx.var.b = 2 ,但是不影响之前的$b变量的值。
测试请求头
在 nginx.conf 不在做修改,就和上面一样!在 request.lua 中 ,添加下面的代码:
--请求头
--定义一个headers变量
local headers = ngx.req.get_headers()
ngx.say("headers begin :","<br/>");
ngx.say("Host : ",headers["Host"],"<br/>")
--两种方式获取user-agent
ngx.say("user-agent : ",headers["user-agent"],"<br/>")
ngx.say("user-agent : ",headers.user_agent,"<br/>")
--for 循环
ngx.say("---for start---","<br/>")
for k,v in pairs(headers) do
if type(v) == "table" then
ngx.say(k ," : " , table.concat(v,","),"<br/>")
else
ngx.say(k , " : ", v ,"<br/>")
end
end
ngx.say("---for end ---","</br>")
local name = headers.name
ngx.say("name is ",name ,"<br/>")
ngx.say("headers end","<br/>")
ngx.say("<br/>")
-- lua中后面的分号可加可不加,不会报错!
测试结果如下:
headers begin :
Host : 192.168.1.110:8080
user-agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
user-agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
---for start---
accept-language : zh-CN,zh;q=0.8
connection : keep-alive
accept : text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
cache-control : no-cache
host : 192.168.1.110:8080
accept-encoding : gzip, deflate
pragma : no-cache
upgrade-insecure-requests : 1
user-agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
---for end ---
name is :nil
headers end
这里参数中没有传name,所以name是nil,这个nil类型java中的null,js中的undefined
name is :nil 也是nil,说明ngx.req.get_headers()不能获取uri参数的值,获取的是header中的值。下面看获取uri参数的值。
测试get请求uri参数
在 nginx.conf 不在做修改,就和上面一样!在 request.lua 中 ,添加下面的代码:
--测试get请求uri参数
ngx.say("get uri args begin ","<br/>")
local uri_args = ngx.req.get_uri_args()
--for循环
ngx.say("headers start","<br/>")
for k,v in pairs(uri_args) do
if type(v) == "table" then
ngx.say(k," : ", table.concat(v,","),"<br/>")
else
ngx.say(k,":",v,"<br/>")
end
end
ngx.say("for end","<br/>")
ngx.say("uri args end ","<br/>")
测试结果:
http://192.168.1.110:8080/luA_requesT/1/20?name=dufy&hello=world
get uri args begin
headers start
hello:world
name:dufy
for end
uri args end
ngx.req.get_uri_args:获取url请求参数,其用法和get_headers类似!
post请求参数 和其他一些api
在 nginx.conf 不在做修改,就和上面一样!在 request.lua 中 ,添加下面的代码:
--获取post请求参数
ngx.req.read_body()
ngx.say("post args begin","<br/>")
local post_args = ngx.req.get_post_args()
for k,v in pairs(post_args) do
if type(v) == "table" then
ngx.say(k,":",table.concat(v,", "),"<br/>")
else
ngx.say(k,": ",v,"<br/>")
end
end
ngx.say("post args end ","<br/>")
--请求http协议版本
ngx.say("ngx.req.http_version : ",ngx.req.http_version(),"<br/>")
--请求方法
ngx.say("ngx.req.get_method : ", ngx.req.get_method(),"<br/>")
--原始请求头内容
ngx.say("ngx.req.raw_header : ",ngx.req.raw_header(),"<br/>")
--请求的body内容体
ngx.say("ngx.req.get_body_data() : " ,ngx.req.get_body_data(),"<br/>")
ngx.say("<br/>")
测试结果:
使用postman发送post请求,如下截图:
ngx.req.http_version : 1.1
ngx.req.get_method : POST
ngx.req.raw_header : POST /luA_requesT/1/20 HTTP/1.1
Host: 192.168.1.110:8080
Connection: keep-alive
Content-Length: 238
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
Cache-Control: no-cache
Origin: chrome-extension://aicmkgpgakddgnaphhhpliifpcfhicfo
X-Postman-Interceptor-Id: 73b998e2-6cad-e3b6-7104-439806d19d25
Content-Type: application/json
Authorization: Basic ZHVmeTo3Mzk0NzU=
Postman-Token: 44e35466-d39a-f2d4-758d-01bb068bbdeb
Accept: */* Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.8 ngx.req.get_body_data() : ------WebKitFormBoundaryPiqJ6rBwM5pdbAd0 Content-Disposition: form-data; name="name" dufy ------WebKitFormBoundaryPiqJ6rBwM5pdbAd0 Content-Disposition: form-data; name="date" 20171107 ------WebKitFormBoundaryPiqJ6rBwM5pdbAd0--
api参数 | 说明 |
---|---|
ngx.var | nginx变量,如果要赋值如ngx.var.b = 2,此变量必须提前声明;另外对于nginx location中使用正则捕获的捕获组可以使用ngx.var[捕获组数字]获取; |
ngx.req.get_headers | 获取请求头,默认只获取前100,如果想要获取所以可以调用ngx.req.get_headers(0);获取带中划线的请求头时请使用如headers.user_agent这种方式;如果一个请求头有多个值,则返回的是table; |
ngx.req.get_uri_args | 获取url请求参数,其用法和get_headers类似; |
ngx.req.get_post_args | 获取post请求内容体,其用法和get_headers类似,但是必须提前调用ngx.req.read_body()来读取body体(也可以选择在nginx配置文件使用lua_need_request_body on;开启读取body体,但是官方不推荐); |
ngx.req.raw_header | 未解析的请求头字符串 |
ngx.req.get_body_data | 为解析的请求body体内容字符串 |
ngx.req.get_method | “post”或者“get”,详情 http-method-constants |
输出响应
api | 说明 |
---|---|
ngx.header | 输出响应头 ,语法: ngx.header.HEADER = VALUE 或者 VALUE = ngx.header.HEADER |
ngx.print | 输出响应内容体 |
ngx.say | 通ngx.print,但是会最后输出一个换行符 |
ngx.exit | 指定状态码退出 |
ngx.redirect | 重定向 |
下面进行相应的测试:
在 nginx.conf 中server添加location:如下:
#測試输出响应的location
location /lua_response_1{
default_type "text/html";
content_by_lua_file learn_lua/req_resp/response_1.lua;
}
location /lua_response_2{
default_type "text/html";
content_by_lua_file learn_lua/req_resp/response_2.lua;
}
在learn_lua目录下新增response_1.lua 和 response_2.lua文件 ,内容分别为
response1.lua
-- 测试写响应头
ngx.header.a = "110"
-- 测试多个响应头可以使用table
ngx.header.b = {
"120","119"}
ngx.header.learn = "openresty"
-- 测试输出响应
ngx.say("a" , "b" ,"<br/>")
ngx.print("c","d","<br/>")
--200状态码退出
return ngx.exit(200)
--这里可以使用http
-- https://github.com/openresty/lua-nginx-module#http-status-constants
-- ngx.HTTP_OK == 2000
-- return ngx.exit(ngx.HTTP_OK)
response2.lua
--跳转到我的博客地址 ngx.redirect("http://blog.csdn.net/u010648555/article/details/78468364", 302)
response1.lua 测试结果:
response2.lua 测试结果跳转到成功!
其他API
api | 说明 |
---|---|
ngx.escape_uri/ngx.unescape_uri | uri编码/解码 |
ngx.encode_args/ngx.decode_args | 参数编码/解码 |
ngx.encode_base64/ngx.decode_base64 | BASE64编码/解码 |
ngx.re.match | nginx正则表达式匹配【下面不讲解,详情看文档】 |
这些api的详细说明可以参考: nginx_modules_lua
在 nginx.conf 中server添加location:如下:
#测试其他的api
location /otherapi_test {
default_type "text/html";
content_by_lua_file learn_lua/req_resp/otherapi_test.lua;
echo_after_body "uri = $uri";
echo_after_body "request_uri = $request_uri";
}
在learn_lua目录下新增 otherapitest.lua ,内容首先为:
--测试其他的一些API
--ngx.var.request_uri 获取$request_uri Nginx 内建变量的值
--ngx.var.uri 获取$uri内置变量的值
-- $uri,可以用来获取当前请求的 URI(经过解码,并且不含请求参数)
-- $request_uri 则用来获取请求最原始的 URI (未经解码,并且包含请求参数)
-- ngx.escape_uri/ngx.unescape_uri|uri编码/解码
local request_uri = ngx.var.request_uri
local uri = ngx.var.uri
ngx.say("------otherapi_test,lua ouput-------","<p/>")
ngx.say("request_uri :" , request_uri, "<br/>")
ngx.say("uri :" , uri, "<br/>")
--解码
ngx.say("decode request_uri", ngx.unescape_uri(request_uri) ,"<br/>")
--编码
ngx.say("encode uri", ngx.escape_uri(uri) ,"<br/>")
-- ngx.encode_args/ngx.decode_args|参数编码/解码
local encode_test1 = ngx.encode_args({foo = 3, ["b r"] = "hello world"})
-- encode_test1 : foo=3&b%20r=hello%20world
ngx.say("encode_test1 : " , encode_test1 ,"<br/>")
--MD5
ngx.say("ngx.md5 : ", ngx.md5("123"), "<br/>")
测试结果显示如下:
ngx.escape_uri/ngx.unescape_uri|uri编码/解码
http://192.168.1.110:8080/otherapi_test/hello world?name=dufy&age=24
------otherapi_test,lua ouput-------
#未经解码,下面使用ngx.unescape_uri解码!
request_uri :/otherapi_test/hello%20world?name=dufy&age=24
#已经解码,下面使用ngx.escape_uri 编码!
uri :/otherapi_test/hello world
decode request_uri/otherapi_test/hello world?name=dufy&age=24
encode uri%2Fotherapi_test%2Fhello%20world # %2F == / ; %20 == 空格
#这个是echo_after_body 输出内容
uri = /otherapi_test/hello world
request_uri = /otherapi_test/hello%20world?name=dufy&age=24
测试参数解码和 MD5 :
encode_test1 : foo=3&b%20r=hello%20world
ngx.md5 : 202cb962ac59075b964b07152d234b70
如果您觉得这篇博文对你有帮助,请点个赞,谢谢!
如果帅气(美丽)、睿智(聪颖),和我一样简单善良的你看到本篇博文中存在问题,请指出,我虚心接受你让我成长的批评,谢谢阅读!
祝你今天开心愉快!
欢迎访问我的csdn博客,我们一同成长!
“不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!”
博客首页:http://blog.csdn.net/u010648555
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/121125.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...