json 解 析 的 异 常 捕 获
local cjson = require "cjson"
local json_str = [[{"name":"ybl}]]
local tab = cjson.decode(json_str)
ngx.say(type(tab))
代码执行错误日志如下:
2016/12/11 11:51:58 [error] 8364#0: *2810371 lua entry thread aborted: runtime error: /web/lua/cc2_demo.lua:167: Expected value but found unexpected end of string at character 14
stack traceback:
coroutine 0:
[C]: in function 'decode'
/web/lua/cc2_demo.lua:167: in function , client: 127.0.0.1, server: localhost, request: "GET /demo HTTP/1.1", host: "127.0.0.1"
如果需要在Lua中处理错误,必须使用函数pcall(protected call)来包装需要执行的代码。pcall接收一个函数和要传递给后者的参数,并执行,执行结果:有错误、无错误;返回值true或者或false, errorinfo。pcall以一种"保护模式"来调用第一个参数,因此pcall可以捕获函数执行中的任何错误。
所以改良一下代码如下
function json_decode( str )
local cjson = require "cjson"
local json_value = nil
pcall(function (str) json_value = cjson.decode(str) end, str)
return json_value
end
local json_str_1 = [[{"name":"ybl}]]
local json_str_2 = [[{"name":"ybl"}]]
local tab1 = json_decode(json_str_1)
local tab2 = json_decode(json_str_2)
ngx.say(type(tab1))
ngx.say(type(tab2))
运行结果:nil 和 table
Lua 中 pairs 和 ipairs 的 区 别
这个新手很容易犯的错,标准库提供了集中迭代器,包括迭代文件每行的(io.lines),迭代table元素的(pairs),迭代数组元素的(ipairs),迭代字符串中单词的,由于在 lua 内部实际采用 哈希表保存键值对、数组保存普通值,table和数组还是有区别的,简单这样理解吧,哈希表是key value类型的, 数组是索引数组,所以在lua中
pairs 可以迭代索引数组和哈希类型的数组
ipairs 可以迭代索引数组,哈希类型的数组不行
首先他们两个效率非常高,比for,while等高很多;ipairs比pairs效率还要高
举例:
local arr_1 = {1,2,3,4,5,6,7,8,9,0}
local arr_2 = {name = "ybl" , age = 22 , sex = "男" , likes = "篮球,跑步,健身"}
local arr_3 = { first="red", "blue", third="green", "yellow"}
针对arr_1,pairs和ipairs都可以迭代,推荐ipairs
针对arr_2,pairs迭代,ipairs空值
针对arr_3,pairs迭代,ipairs空值
非空判断
这里的ken狠多,用如下封装的方法就可以,如果你想了解更多,可查看OpenResty最佳实践
function isTableEmpty(t)
if t == nil or next(t) == nil then
return true
else
return false
end
end
lua获取GET 和 POST参数
function getpost()
local args = {}
local request_method = ngx.var.request_method
if "GET" == request_method then
args = ngx.req.get_uri_args()
elseif "POST" == ngx.req.get_method() then
ngx.req.read_body()
args = ngx.req.get_post_args()
end
return args
end
lua获取请求 body-适合获取http请求post和get参数【推荐】
ngx.req.get_body_data() 读请求体,会偶尔出现读取不到直接返回 nil 的情况。
所以得事先调用ngx.req.read_body(),强制本模块读取请求体
ngx.req.read_body()
local json_str = ngx.req.get_body_data()
--如果是json,则可以转化为table等等。。。
lua发起http get和post请求
function http_post(url,table_par)
local http = require "http"
local httpc = http.new()
local res, err = httpc:request_uri(url,{
method = 'POST',
body = cjson.encode(table_par),
headers = {["Content-Type"] = "application/x-www-form-urlencoded",}
})
if not res then
return 100
end
return res.body
end
function comm_fun:http_get(url,table_par)
local http = require "http"
local httpc = http:new()
local res, err = httpc:request_uri(url, {
method = "GET",
query = table_par,
--ssl_verify = false, -- 需要关闭这项才能发起https请求
headers = {["Content-Type"] = "application/x-www-form-urlencoded" },
})
if not res then
return 100
end
return res.body
end
Lua获取请求者的ip,浏览器,系统等信息
function getBrowser()
local user_agent = ngx.req.raw_header()
local browser = "others"
if ngx.re.match(user_agent,"Chrome") then
browser = "Chrome"
elseif ngx.re.match(user_agent,"Firefox") then
browser = "Firefox"
elseif ngx.re.match(user_agent,"QQBrowser") then
browser = "QQBrowser"
elseif ngx.re.match(user_agent,"Safari") then
browser = "Safari"
elseif ngx.re.match(user_agent,"Opera") then
browser = "Opera"
elseif ngx.re.match(user_agent,"MSIE 11.0") or ngx.re.match(user_agent,"rv:11.0") then
browser = "IE 11.0"
elseif ngx.re.match(user_agent,"MSIE 10.0") or ngx.re.match(user_agent,"rv:10.0") then
browser = "IE 10.0"
elseif ngx.re.match(user_agent,"MSIE 9.0") or ngx.re.match(user_agent,"rv:9.0") then
browser = "IE 9.0"
elseif ngx.re.match(user_agent,"MSIE 8.0") or ngx.re.match(user_agent,"rv:8.0") then
browser = "IE 8.0"
elseif ngx.re.match(user_agent,"MSIE 7.0") or ngx.re.match(user_agent,"rv:7.0") then
browser = "IE 7.0"
elseif ngx.re.match(user_agent,"MSIE 6.0") or ngx.re.match(user_agent,"rv:6.0") then
browser = "IE 6.0"
else
browser = "others"
end
return browser
end
function getSystem()
local user_agent = ngx.req.raw_header()
local system = "others"
if ngx.re.match(user_agent,"Mac OS") then
system = "Mac OS"
elseif ngx.re.match(user_agent,"Mac") then
system = "Macintosh"
elseif ngx.re.match(user_agent,"Windows NT 10.0") then
system = "Windows 10"
elseif ngx.re.match(user_agent,"Windows NT 6.2") then
system = "Windows 8"
elseif ngx.re.match(user_agent,"Windows NT 6.1") then
system = "Windows 7"
elseif ngx.re.match(user_agent,"Windows NT 6.0") then
system = "Windows Vista"
elseif ngx.re.match(user_agent,"Windows NT 5.1") then
system = "Windows XP"
elseif ngx.re.match(user_agent,"Windows NT 5.0") then
system = "Windows 2000"
elseif ngx.re.match(user_agent,"linux") then
system = "Linux"
elseif ngx.re.match(user_agent,"unix") then
system = "Unix"
elseif ngx.re.match(user_agent,"FreeBSD") then
system = "FreeBSD"
elseif ngx.re.match(user_agent,"IRIX") then
system = "IRIX"
elseif ngx.re.match(user_agent,"OSF1") then
system = "OSF1"
elseif ngx.re.match(user_agent,"BSD") then
system = "BSD"
elseif ngx.re.match(user_agent,"NetBSD") then
system = "NetBSD"
elseif ngx.re.match(user_agent,"HPUX") then
system = "HPUX"
elseif ngx.re.match(user_agent,"AIX") then
system = "AIX"
elseif ngx.re.match(user_agent,"PowerPC") then
system = "PowerPC"
elseif ngx.re.match(user_agent,"sun") then
system = "SUN"
elseif ngx.re.match(user_agent,"ibm") then
system = "IBM"
end
return system
end
function getIP()
return ngx.var.remote_addr
end
通过FFI的方式加载其他C接口动态库来获取系统
local ffi = require("ffi")
if ffi.os == "Windows" then
ngx.say("windows")
elseif ffi.os == "OSX" then
ngx.say("MAC OS X")
else
ngx.say(ffi.os)
end