【发布时间】:2021-07-24 04:08:28
【问题描述】:
我正在尝试解析通过 POST 请求发送到 NGINX/Openresty location 的 json 有效负载。为此,我将 Openresty 的 content_by_lua_block 与其 cjson module 结合起来,如下所示:
# other locations above
location /test {
content_by_lua_block {
ngx.req.read_body()
local data_string = ngx.req.get_body_data()
local cjson = require "cjson.safe"
local json = cjson.decode(data_string)
local endpoint_name = json['endpoint']['name']
local payload = json['payload']
local source_address = json['source_address']
local submit_date = json['submit_date']
ngx.say('Parsed')
}
}
解析包含所有必填字段的示例数据按预期工作。正确的 JSON 对象可能如下所示:
{
"payload": "the payload here",
"submit_date": "2018-08-17 16:31:51",
},
"endpoint": {
"name": "name of the endpoint here"
},
"source_address": "source address here",
}
但是,用户可能会将不同格式的 JSON 对象发布到 location。假设一个简单的 JSON 文档,如
{
"username": "JohnDoe",
"password": "password123"
}
不包含所需的字段/键。
根据cjson module docs,如果遇到无效数据,使用cjson(没有safe 模式)将引发错误。为了防止出现任何错误,我决定通过导入cjson.safe 来使用它的safe 模式。这应该为无效数据返回 nil 并提供错误消息而不是引发错误:
如果遇到任何无效数据,
cjson模块将在 JSON 转换期间抛出错误。 [...]
cjson.safe模块的行为与 cjson 模块相同,除非在 JSON 转换期间遇到错误。出错时,cjson_safe.encode和cjson_safe.decode函数将返回 nil,后跟错误消息。
但是,在我的案例中,我没有遇到任何不同的错误处理行为,Openresty 的 error.log 文件中显示了以下回溯:
2021/04/30 20:33:16 [error] 6176#6176: *176 lua entry thread aborted: runtime error: content_by_lua(samplesite:50):16: 尝试索引字段“endpoint”(一个 nil 值)
这又会导致内部服务器错误:
<html>
<head><title>500 Internal Server Error</title></head>
<body>
<center><h1>500 Internal Server Error</h1></center>
<hr><center>openresty</center>
</body>
</html>
我认为一种解决方法可能是编写一个专门的函数来解析 JSON 数据并使用 pcall() 调用它来捕获任何错误。但是,这会使safe 模式变得毫无用处。我在这里错过了什么?
【问题讨论】:
标签: json nginx lua openresty cjson