javascript - 安全地处理 Node 中的错误 JSON.parse()

标签 javascript json node.js express

使用 Node/ express - 我想从请求 header 中获取一些 JSON,但我想安全地做到这一点。
如果由于某种原因它不是有效的 JSON,那很好,它可以返回 false 或其他什么,它只会拒绝请求并继续。问题是如果它不是有效的 JSON,它会引发语法错误。通常我希望出现语法错误,但在这种情况下不会。

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

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

编辑: 我知道 try/catch block 是处理此错误的 A 方式,但它是 Node 应用程序中的最佳方式吗?这种方式会阻塞 Node 吗?

最佳答案

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

您确实没有任何其他选择 - 内置实现会在无效 JSON 数据上引发异常,防止该异常停止应用程序的唯一方法是捕获它。即使使用 3rd 方库也无法避免这种情况 - 他们必须在某处调用 JSON.parse() 进行 try/catch

唯一的选择是实现您自己的 JSON 解析算法,该算法可能对无效数据结构更宽容,但这感觉就像用小核弹挖一个 1 立方米的洞。

关于性能的说明

Node.js 使用的 v8 JavaScript 引擎 cannot optimise包含 try/catch block 的函数。

更新: v8 4.5 and above can optimise 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 中的 every.single.statement 的 JavaScript 代码一次只执行一次,无论是从主函数调用还是从回调或来自不同的模块或其他。因此,每一条语句都会阻塞该过程。这不一定是坏事——一个设计良好的应用程序将花费大部分时间等待外部资源(数据库响应、HTTP 通信、文件系统操作等)。因此,非常重要的是 v8 引擎可以优化频繁执行的 JavaScript 代码,以便在这种阻塞状态下花费尽可能少的时间 - 请参阅有关性能的说明。

关于javascript - 安全地处理 Node 中的错误 JSON.parse(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29797946/

相关文章:

javascript - 将变量传递给自动完成 JavaScript

javascript - 如何禁用 bsdatePicker 中的 future 日期

json - 网站创建失败,找不到服务器场 Azure Powershell

java - Gson自定义反序列化但只有一个字段

c# - 从 API 获取数字并将其放入变量中

javascript - 检查 Node.js 中的事件对象/堆栈

node.js - Passport 失败并出现 404 - GitHub 的 InternalOAuthError 为什么?

javascript - Firefox 中的不平滑 div 动画

php - 像 facebook 一样将 facebook 时区转换为我的本地时区

mysql - 如何将 Node.js/passport 合并到我的网站中?