json 解 析 的 異 常 捕 獲
local cjson ? ? ?= require "cjson"
local json_str? = [[{"name":"ybl}]]
local tab ? ? ? ? = cjson.decode(json_str)
ngx.say(type(tab))
代碼執(zhí)行錯誤日志如下:
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中處理錯誤,必須使用函數(shù)pcall(protected call)來包裝需要執(zhí)行的代碼。pcall接收一個函數(shù)和要傳遞給后者的參數(shù),并執(zhí)行,執(zhí)行結果:有錯誤、無錯誤;返回值true或者或false, errorinfo。pcall以一種"保護模式"來調(diào)用第一個參數(shù),因此pcall可以捕獲函數(shù)執(zhí)行中的任何錯誤。
所以改良一下代碼如下
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 的 區(qū) 別
這個新手很容易犯的錯,標準庫提供了集中迭代器,包括迭代文件每行的(io.lines),迭代table元素的(pairs),迭代數(shù)組元素的(ipairs),迭代字符串中單詞的,由于在 lua 內(nèi)部實際采用 哈希表保存鍵值對、數(shù)組保存普通值,table和數(shù)組還是有區(qū)別的,簡單這樣理解吧,哈希表是key value類型的, 數(shù)組是索引數(shù)組,所以在lua中
pairs? 可以迭代索引數(shù)組和哈希類型的數(shù)組
ipairs 可以迭代索引數(shù)組,哈希類型的數(shù)組不行
首先他們兩個效率非常高,比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參數(shù)
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參數(shù)【推薦】
ngx.req.get_body_data() 讀請求體,會偶爾出現(xiàn)讀取不到直接返回 nil 的情況。
所以得事先調(diào)用ngx.req.read_body(),強制本模塊讀取請求體
ngx.req.read_body()
local json_str = ngx.req.get_body_data()
--如果是json,則可以轉化為table等等。。。
lua發(fā)起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, -- 需要關閉這項才能發(fā)起https請求
? ? ? ? ? ? ? ? ? ? ? ? ? ?headers = {["Content-Type"] = "application/x-www-form-urlencoded" },
? ? ? ? ? ? ? })
? ? ? ? ? ? ? if not res then
? ? ? ? ? ? ? ? ? ? ? ? ? ?return 100
? ? ? ? ? ? ? ?end
? ? ? ? ? ? ? ?return res.body
? ? end
Lua獲取請求者的ip,瀏覽器,系統(tǒng)等信息
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接口動態(tài)庫來獲取系統(tǒng)
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