使用节点/快递 - 我想从请求标题中获取一些JSON,但我想安全地完成它 如果由于某种原因它不是有效的JSON,它没关系,它只能返回false或者其他什么,它只会拒绝请求并继续运行。问题是,如果它不是有效的JSON,它会抛出语法错误。通常我希望语法错误爆炸,但不是在这种情况下。
var boom = JSON.parse(req.headers.myHeader);
我是否刮掉堆栈并检查来自该特定模块的错误解析调用,如果是这样,它会忽略它?这看起来有点疯狂。当然有更好的方法。
编辑: 我知道try / catch块是 A 处理此错误的方式,但它是节点应用程序中的最佳方式吗?这样会阻塞节点吗?
答案 0 :(得分:49)
捕获无效JSON解析错误的最佳方法是将对JSON.parse()
的调用置于try/catch
块。
你真的没有任何其他选择 - 内置实现会对无效的JSON数据抛出异常,防止该异常暂停应用程序的唯一方法就是捕获它。即使使用第三方图书馆也无法避免这种情况 - 他们必须在try/catch
某个地方JSON.parse()
拨打try/catch
。
唯一的选择是实现自己的JSON解析算法,这种算法可能对无效数据结构更加宽容,但这就像用一个小核心挖一个1立方米的洞一样。
包含function safelyParseJSON (json) {
// This function cannot be optimised, it's best to
// keep it small!
var parsed
try {
parsed = JSON.parse(json)
} catch (e) {
// Oh well, but whatever...
}
return parsed // Could be undefined!
}
function doAlotOfStuff () {
// ... stuff stuff stuff
var json = safelyParseJSON(data)
// Tadaa, I just got rid of an optimisation killer!
}
块的Node.js cannot optimise函数使用的v8 JavaScript引擎。
更新: v8 4.5 and above can optimise try/catch。对于旧版本,请参阅下文。
一个简单的解决方法是将安全解析逻辑放入一个单独的函数中,以便仍然可以优化main函数:
select * from contacts where title ilike '%cto%';
如果偶尔进行JSON解析,这可能不会对性能产生明显影响,但如果在使用量较大的函数中使用不当,可能会导致响应时间大幅增加。
需要注意的是,Node.js中的JavaScript代码的 every.single.statement 只能一次执行一次,无论是从主函数调用还是从回调或来自不同的模块或其他。因此,每个语句都会阻止该过程。这不一定是坏事 - 设计良好的应用程序将花费大部分时间等待外部资源(数据库响应,HTTP通信,文件系统操作等)。因此,非常重要的是,v8引擎可以优化频繁执行的JavaScript代码,因此在这种阻塞状态下花费尽可能少的时间 - 请参阅有关性能的说明。
答案 1 :(得分:8)
您可以使用try
和catch
function parseMyHeader(){
try {
return JSON.parse(req.headers.myHeader);
} catch(ex){
return null;
}
}
答案 2 :(得分:3)
标准的try / catch是处理node.js中JSON.parse错误的正确方法,如joyent网站的节点production practices for error handling文档中所述,该文档说:
...你使用try / catch的唯一常用情况是JSON.parse 和其他用户输入验证功能。
这也与Aleksandr在评论中提供的nodejitsu链接一致。
答案 3 :(得分:0)
var parsed;
try {
parsed = JSON.parse(data);
} catch (e) {
parsed = JSON.parse(JSON.stringify(data));
}
root = parsed;
这对我有用。 在Catch中,我将数据转换为stringify,然后再将其解析为JSON。
答案 4 :(得分:0)
这是关于如何在异常
期间不破坏脚本Promise.resolve((body)=>{
let fbResponse = JSON.parse(body);
// some code for good
}).catch(error => {
cl('Parsing error:');
cl(error);
// some code for bad
});