如何在不使用 Try/Catch 的情况下检查字符串是否为 JavaScript 中的有效 JSON 字符串

IT技术 javascript json
2021-01-28 21:03:07

就像是:

var jsonString = '{ "Id": 1, "Name": "Coke" }';

//should be true
IsJsonString(jsonString);

//should be false
IsJsonString("foo");
IsJsonString("<div>foo</div>")

解决方案不应包含 try/catch。我们中的一些人打开“中断所有错误”,他们不喜欢调试器中断那些无效的 JSON 字符串。

6个回答

使用 JSON 解析器,如JSON.parse

function IsJsonString(str) {
    try {
        JSON.parse(str);
    } catch (e) {
        return false;
    }
    return true;
}
@Carcigenicate 你可以这样做。但是,JSON.parse("false")评估结果也为false
2021-03-19 21:03:07
@trejder:这样做是因为 1 不是字符串,请尝试使用“1”
2021-03-28 21:03:07
谢谢,但我只是和团队一起运行了这个,他们想要一些不使用 try/catch 的东西。该问题与新标题一起编辑。对于那个很抱歉。
2021-03-29 21:03:07
@Gumbo 我的评论是 1,5 岁!:] 我不记得了,两周前我在做什么,你让我回忆那个项目?:] 没门... :]
2021-04-04 21:03:07
这个答案的问题是,如果字符串确实检出,并且您解析它,您将解析它两次。难道您不能在解析错误时返回 false,但在成功时返回对象吗?
2021-04-09 21:03:07

我知道我问这个问题晚了 3 年,但我想插话说。

虽然 Gumbo 的解决方案效果很好,但它不能处理一些没有引发异常的情况 JSON.parse({something that isn't JSON})

我也更喜欢同时返回解析后的 JSON,这样调用代码就不必JSON.parse(jsonString)第二次调用了。

这似乎很适合我的需求:

/**
 * If you don't care about primitives and only objects then this function
 * is for you, otherwise look elsewhere.
 * This function will return `false` for any valid json primitive.
 * EG, 'true' -> false
 *     '123' -> false
 *     'null' -> false
 *     '"I'm a string"' -> false
 */
function tryParseJSONObject (jsonString){
    try {
        var o = JSON.parse(jsonString);

        // Handle non-exception-throwing cases:
        // Neither JSON.parse(false) or JSON.parse(1234) throw errors, hence the type-checking,
        // but... JSON.parse(null) returns null, and typeof null === "object", 
        // so we must check for that, too. Thankfully, null is falsey, so this suffices:
        if (o && typeof o === "object") {
            return o;
        }
    }
    catch (e) { }

    return false;
};
在页面上的答案中,这是最可靠和最可靠的。
2021-03-31 21:03:07
o && o !== null 是多余的。
2021-03-31 21:03:07
该函数应该返回undefined,而不是false因为它false是一个有效的 json 字符串并且无法区分tryParseJSON("false")tryParseJSON("garbage")
2021-04-03 21:03:07
尽管是旧帖子,但我认为值得摆弄一下来证明您的答案@matth,请注意对象将无效..您必须传递一个 JSON 字符串。我猜可能对任何刚开始的人都会派上用场。
2021-04-07 21:03:07
使用带有 typeof 的三等号也是如此,它总是返回一个字符串。:)
2021-04-08 21:03:07

先评论一下。问题是关于不使用try/catch.
如果您不介意使用它,请阅读下面的答案。这里我们只是JSON使用正则表达式检查字符串,它在大多数情况下都有效,而不是所有情况。

看看https://github.com/douglascrockford/JSON-js/blob/master/json2.js 中的第 450 行

有一个检查有效 JSON 的正则表达式,例如:

if (/^[\],:{}\s]*$/.test(text.replace(/\\["\\\/bfnrtu]/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

  //the json is ok

}else{

  //the json is not ok

}

编辑:新版本的 json2.js 进行了比上面更高级的解析,但仍然基于正则表达式替换(来自@Mrchief评论

您无法使用 JavaScript 中的正则表达式测试字符串是否是有效的 JSON,因为 JS 正则表达式不支持允许您这样做的必要扩展(递归正则表达式)。您上面的代码在“{”上失败。
2021-03-10 21:03:07
这只是检查代码对于 eval 使用是否安全。例如,以下字符串 '2011-6-27' 将通过该测试。
2021-03-15 21:03:07
@Mic json2.js 不再使用这种简单的检查(而是使用 4 阶段解析来确定有效的 JSON)。建议修改或删除您的答案。请注意,我认为“没有将 try/catch 作为检查 JSON 的唯一机制”作为一种方法没有任何错误。
2021-03-18 21:03:07
仅仅因为它对他有帮助,并不意味着它可以帮助我们其他人,多年后,他们也有同样的问题。
2021-03-21 21:03:07
@SystemicPlural,是的,但问题是不使用 try/catch
2021-03-25 21:03:07
// vanillaJS
function isJSON(str) {
    try {
        return (JSON.parse(str) && !!str);
    } catch (e) {
        return false;
    }
}

用法: isJSON({})将是falseisJSON('{}')将是true

要检查某个东西是否是一个ArrayObject解析的JSON):

// vanillaJS
function isAO(val) {
    return val instanceof Array || val instanceof Object ? true : false;
}

// ES2015
var isAO = (val) => val instanceof Array || val instanceof Object ? true : false;

用法: isAO({})将是trueisAO('{}')将是false

由于null通过了此验证,因此请小心
2021-03-26 21:03:07
这是最好的答案,因为它还允许您检查 JSON 是否已被对象,从而未通过parse()测试,从而导致 WTF。
2021-03-28 21:03:07
return !!(JSON.parse(str) && str);应该阻止空值。我将使用此代码更新答案。
2021-03-29 21:03:07

这是我的工作代码:

function IsJsonString(str) {
  try {
    var json = JSON.parse(str);
    return (typeof json === 'object');
  } catch (e) {
    return false;
  }
}
null代表 an 的空值object,所以从我的角度来看这看起来不错......它可能不适用于您的特定场景,但它就是这样
2021-03-19 21:03:07
IsJsonString(null); //返回真。可以通过比较确定typeof str === 'string'
2021-04-03 21:03:07