【问题标题】:How can I safely use JSON.parse on a string object that might be a simple string or a string object?如何在可能是简单字符串或字符串对象的字符串对象上安全地使用 JSON.parse?
【发布时间】:2015-10-08 16:43:29
【问题描述】:

我需要能够解析对象格式或纯字符串格式的字符串。这样做最安全的方法是什么?

我试过 JSON.parse(data) 但如果数据是纯字符串,它就不起作用。


编辑 - 选择的解决方案

多亏了你,这就是我解决问题的方法:

try {
    dataObj = JSON.parse(data);
} catch (err) {
    if (typeof data === "object") {
        dataObj = data;
    } else {
        dataObj = {};
    }
}

【问题讨论】:

  • 如果data 可以是一个对象,你为什么不测试一下 before 你试图解析它?那会更有意义。另外,如果它可以是一个对象,你为什么不在你的问题中提到呢?你说这个值是一个字符串。
  • 写完这个问题后,我发现了更多的边缘案例。

标签: javascript json string parsing


【解决方案1】:

使用try catch:

var result;
try {
   result = JSON.parse(data);
} catch (err) {
   if (typeof data == 'string') result = data;
   else console.error(err);
}

【讨论】:

  • 现在的问题不是如何区分无效 JSON 和“纯字符串”导致的错误吗? (第一个是意料之外的,第二个是意料之中的)或者你认为如果数据包含 JSON,它总是有效的?
  • 已修复:if (typeof data == 'string') result = data;否则 console.error(err);
  • 嗯,你为什么期望data 不是字符串?您是否将 JSON 与 JavaScript 对象混淆了?
  • 同意@FelixKling,检查需要在所有情况下都是安全的。
【解决方案2】:

为自己创建一个辅助函数并使用它。

function parseValue(value) {
    try
    {
        return JSON.parse(value);
    }
    catch (ex)
    {
        // JSON format was invalid
        // handle errors is you need to
    }

    return value;
}

如果你足够勇敢,你还可以扩展 String.prototype,这样调用它就会变得非常简单。

String.prototype.parseJSON = String.prototype.parseJSON || function() {
    try
    {
        return JSON.parse(this);
    }
    catch (ex)
    {
        // JSON format was invalid
        // handle errors is you need to
    }

    return this;
};

然后你可以这样称呼它:

// string in a variable
var s = "Some non-JSON string";
s.parseJSON();
// string literal
'{"b":true,"n":1}'.parseJSON();

【讨论】:

  • 只是指出这种方法的“问题”(这并不意味着这是一个糟糕的解决方案!):正如已经说过的try/catch 处理每个错误,但实际上我们有两个错误情况可能要区分:1)输入是格式错误的JSON。这是一个意外错误,在这种情况下可能应该修复 JSON 生成。 2)输入是纯字符串。这是意料之中的,因此程序应该继续运行。不过公平地说,如果 JSON 是使用本机函数生成的,那么情况 1 不太可能发生。在此假设下,try/catch 是合适的解决方案。
【解决方案3】:

假设 JSON 始终具有相同的格式,您还可以检查字符串是否以 {"(或只是 {)开头,然后才使用 JSON.parse 解析它。

这确实取决于可能的输入。

【讨论】:

  • 这很好,但是您最终会更改您的代码,而try/catch 涵盖了所有内容...我是什么意思? JSON 对象可以以{ 开头,也可以以[ 开头。但这些只是我脑海中的那些。 JSON 字符串可能还有其他开头。因此,为了让您的代码更加防弹以涵盖我认为try/catch 的任何字符串,这是一种更好的方法。
  • @Robert:这完全取决于上下文和可能的输入。 try...catch 的缺点是你错过了 JSON 真正被破坏的情况,那么这真的更防弹吗?顺便说一句,[ 表示一个数组,而不是一个对象。根据他们的说法,我假设如果它是 JSON,它将始终是一个对象。
  • @FelixKling:那么你在哪里处理像{{ this is worth nothing }} 这样的无效JSON? try/catch 可以在这种情况下工作,而您的 if/else认为它是 JSON,并且在解析它时会出错。
  • @Robert:我希望它抛出一个错误,以便我了解它。如果你默默地抓住它,你更有可能不知道有问题。
  • 但在浏览器中抛出的错误不会显示给用户,您作为开发人员必须处理它们并向您的用户提供人类可读的错误信息。这实际上意味着什么?你最终也会得到一个try/catch 块。那么,如果您可以在处理错误的地方使用try/catch 覆盖所有内容,那么为什么还要使用if/else
猜你喜欢
  • 1970-01-01
  • 2017-07-18
  • 2015-08-29
  • 2012-10-11
  • 1970-01-01
  • 2018-06-26
  • 1970-01-01
  • 1970-01-01
  • 2010-09-07
相关资源
最近更新 更多