在节点中安全地处理错误的JSON.parse()

使用节点/快递 – 我想从请求头获得一些JSON,但我想安全地做到这一点。
如果由于某种原因,它不是有效的JSON,没关系,它可以只是返回false或其他什么,它只会拒绝请求,并继续前进。 问题是如果它不是有效的JSON,则会引发语法错误。 通常我想要一个语法错误炸毁,但不是在这种情况下。

var boom = JSON.parse(req.headers.myHeader);

我是否刮了堆栈,并检查来自特定模块的错误parsing调用,如果是这种情况,它会忽略它? 这似乎有点疯狂。 当然有更好的方法。

编辑:我知道try / catch块是处理此错误的一种方式,但它是节点应用程序中的最佳方式? 这样可以阻止节点吗?

捕获无效JSONparsing错误的最佳方法是将调用JSON.parse()放到try/catch块中。

你真的没有其他的select – 内置的实现抛出无效的JSON数据的exception,防止这种exception停止你的应用程序的唯一方法就是捕捉它。 即使使用第三方库也不能避免 – 他们必须在某个地方执行JSON.parse()调用。

唯一的select是实现自己的JSONparsingalgorithm,这个algorithm可以在无效的数据结构上更宽容,但是感觉就像挖一个1立方米的小洞一样。

关于性能的说明

Node.js使用的v8 JavaScript引擎无法优化包含try/catch块的函数。

更新: v8 4.5及以上版本可以优化try / catch 。 对于旧版本,请参见下文。

一个简单的解决方法是将安全parsing逻辑放入一个单独的函数中,这样主函数仍然可以被优化:

 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! } 

如果JSONparsing是偶尔进行的,这可能对性能没有明显影响,但是如果在使用繁重的function中使用不当,可能会导致响应时间急剧增加。

关于try / catch被阻塞的注意事项

需要注意的是,Node.js中的每一个单独的JavaScript代码只能一次执行一次,不pipe是从主函数调用,还是从callback函数或者从其他模块调用。 因此,每一个陈述都会阻止这个过程。 这不一定是坏事 – devise良好的应用程序将花费大部分时间等待外部资源(数据库响应,HTTP通信,文件系统操作等)。 因此,经常执行的JavaScript代码可以通过v8引擎进行优化,所以在这种阻塞状态下尽可能less的时间是非常重要的 – 请参阅关于性能的说明。

你可以使用trycatch

 function parseMyHeader(){ try { return JSON.parse(req.headers.myHeader); } catch(ex){ return null; } } 

标准的try / catch是处理node.js中的JSON.parse错误的正确方法,正如joyent网站的error handling文档的节点生产实践中所述的那样:

…使用try / catch的唯一常用的情况是JSON.parse和其他用户inputvalidation函数。

这也与Aleksandr在评论中提供的与nodejitsu的链接相一致。

  var parsed; try { parsed = JSON.parse(data); } catch (e) { parsed = JSON.parse(JSON.stringify(data)); } root = parsed; 

那么这为我工作。 在Catch中,我将数据转换为stringify,然后将其parsing为JSON。