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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29797946/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:00:44  来源:igfitidea点击:

Handling bad JSON.parse() in node safely

javascriptjsonnode.jsexpress

提问by tpie

Using node/express - I want to get some JSON out of request headers, but I want to do it safely.
If for some reason it's not valid JSON, it's fine, it can just return false or whatever and it will just reject the request and keep going. The problem is it throws a syntax error if it's not valid JSON. Normally I want a syntax error to blow up, but not in this case.

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

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

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

Do I scrape the stack and check for a bad parse call from that particular module, and if it's the case, it ignores it? That seems a bit crazy. Surely there's a better way.

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

EDIT: I am aware that try/catch blocks are Away of handling this error, but is it the best way in a node app? Will this way block node?

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

回答by Robert Rossmann

The best way to catch invalid JSON parsing errors is to put the calls to JSON.parse()to a try/catchblock.

赶上无效JSON解析错误,最好的办法是把调用JSON.parse()try/catch块。

You really do not have any other option - the built-in implementation throws an exception on invalid JSON data and the only way to prevent that exception from halting your application is to catch it. Even using a 3rd party library will not avoid that - they must do a try/catchon a JSON.parse()call somewhere.

您真的没有任何其他选择 - 内置实现会在无效的 JSON 数据上引发异常,而防止该异常停止应用程序的唯一方法是捕获它。即使使用第 3 方库也无法避免这种情况——他们必须try/catchJSON.parse()某个地方打电话。

The only alternative is to implement your own JSON parsing algorithm that could be more forgiving on invalid data structures, but that feels like digging a 1 cubic metre hole with a small nuke.

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

Note about performance

性能注意事项

The v8 JavaScript engine used by Node.js cannot optimisefunctions which contain a try/catchblock.

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

Update:v8 4.5 and above can optimise try/catch. For older releases, see below.

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

A simple workaround is to put the safe-parsing logic into a separate function so that the main function can still be optimised:

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

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

If the JSON parsing is done sporadically, this might not have a noticeable effect on performance, but if used improperly in usage-heavy function it could lead to dramatic increase in response times.

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

Note about try/catch being blocking

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

It should be noted that every.single.statementof JavaScript code in Node.js is executed only one-at-a-time, no matter if it's called from the main function or from a callback or from a different module or whatever. As such, every single statement will blockthe process. This is not necessarily a bad thing - a well designed application will spend most of its time waiting for an external resource (database response, HTTP communication, filesystem operations etc.). It is therefore of great importance that frequently executed JavaScript code can be optimised by the v8 engine so it takes as little time as possible in this blocked state - see the note about performance.

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

回答by EJTH

You can use tryand catch

您可以使用trycatch

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

回答by tpie

The standard try/catch is the correct way to handle a JSON.parse error in node.js, as mentioned in the node production practices for error handlingdocs from the joyent website, which says:

标准的 try/catch 是在 node.js 中处理 JSON.parse 错误的正确方法,正如在Joyent 网站的错误处理文档的节点生产实践中提到的,它说:

...the only commonly-used case where you'd use try/catch is JSON.parse and other user-input validation functions.

...您使用 try/catch 的唯一常用情况是 JSON.parse 和其他用户输入验证函数。

Which is also in agreement with the link to nodejitsu which Aleksandr supplied in his comment.

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

回答by Ganesh Todkar

        var parsed;

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

        root = parsed;

Well this worked for me. In Catch I converted the data to stringify before parsing it to JSON.

嗯,这对我有用。在 Catch 中,我将数据转换为 stringify,然后再将其解析为 JSON。

回答by user3640561

This is about how to not break script during exception

这是关于如何在异常期间不破坏脚本

Promise.resolve((body)=>{
            let fbResponse = JSON.parse(body);
            // some code for good
        }).catch(error => {
            cl('Parsing error:');
            cl(error);
            // some code for bad
        });