一尘不染

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

node.js

使用node / express-我想从请求标头中获取一些JSON,但我想安全地做到这一点。
如果由于某种原因它不是有效的JSON,那很好,它可以返回false或其他任何值,它将拒绝请求并继续执行。问题是,如果它不是有效的JSON,则会引发语法错误。通常,我希望语法错误能够爆发,但在这种情况下不希望。

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

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

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


阅读 318

收藏
2020-07-07

共1个答案

一尘不染

捕获无效的JSON解析错误的最佳方法是将调用放入JSON.parse()一个try/catch块中。

您确实没有其他选择-内置的实现会对无效的JSON数据引发异常,并且防止该异常停止您的应用程序的唯一方法是捕获它。即使使用第三方库也无法避免-
他们必须try/catchJSON.parse()某个地方进行呼叫。

唯一的选择是实现自己的JSON解析算法,该算法可以更有效地处理无效的数据结构,但是感觉就像用一个小核子挖了一个1立方米的孔。

关于性能的注意事项

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

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

一个简单的解决方法是将安全解析逻辑放入单独的函数中,以便仍可以优化主要函数:

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

如果偶尔进行JSON解析,这可能不会对性能产生明显影响,但是如果在使用率偏高的函数中使用不当,可能会导致响应时间急剧增加。

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

应当注意, Node.js中
的JavaScript代码的每个声明都一次只能执行一次,无论是从主函数,回调还是从其他模块或其他任何函数调用它。这样,每条语句 都会阻塞
该过程。这并不一定是一件坏事-
一个设计良好的应用程序将花费大部分时间来等待外部资源(数据库响应,HTTP通信,文件系统操作等)。因此,非常重要的是可以通过v8引擎优化频繁执行的JavaScript代码,以便在这种阻塞状态下花费尽可能少的时间-
请参阅有关性能的说明。

2020-07-07