如何测试字符串是否为 JSON?

IT技术 javascript mysql json
2021-01-12 23:17:02

我有一个简单的 AJAX 调用,服务器将返回包含有用数据的 JSON 字符串或由 PHP 函数生成的错误消息字符串mysql_error()如何测试此数据是 JSON 字符串还是错误消息。

使用一个被调用的函数会很好,isJSON就像你可以使用该函数instanceof来测试某个东西是否是一个数组一样。

这就是我要的:

if (isJSON(data)){
    //do some data stuff
}else{
    //report the error
    alert(data);
}
6个回答

使用 JSON.parse

function isJson(str) {
    try {
        JSON.parse(str);
    } catch (e) {
        return false;
    }
    return true;
}
不应该使用异常处理来做一些预期的事情。
2021-03-27 23:17:02
JSON.parse进行大量计算来解析字符串,如果成功则为您提供 json 对象,但您丢弃了某些用户可能想要使用的结果。这似乎不太好。我改为return {value: JSON.parse(str), valid: true};在 catch 块中return {value: str, valid: false};.. 并将函数名称更改为tryParse().
2021-03-29 23:17:02
@Zalaboza 12340falsenull都是有效的 JSON 值。如果您想要一个测试 JSON 是否代表一个对象的谓词,您需要做更多的工作。
2021-04-01 23:17:02
JSON.parse(1234)OR JSON.parse(0)OR JSON.parse(false)OR JSON.parse(null)all 不会引发 Exception 并且会返回 true !!。不要使用这个答案
2021-04-02 23:17:02
@luisZavaleta 那么你有什么建议作为方法
2021-04-09 23:17:02

此代码 is JSON.parse(1234)or JSON.parse(0)or JSON.parse(false)or JSON.parse(null)all 将返回 true。

function isJson(str) {
    try {
        JSON.parse(str);
    } catch (e) {
        return false;
    }
    return true;
}

于是我这样重写了代码:

function isJson(item) {
    item = typeof item !== "string"
        ? JSON.stringify(item)
        : item;

    try {
        item = JSON.parse(item);
    } catch (e) {
        return false;
    }

    if (typeof item === "object" && item !== null) {
        return true;
    }

    return false;
}

测试结果:

isJson 测试结果

如果您使用此功能测试 .srt 文件(字幕文件),它将为真。
2021-03-13 23:17:02
干得好!您的最后一个 if 语句可以简化为一个简单的 return 语句,例如:return (typeof suspect === "object" && suspect !== null);
2021-04-03 23:17:02

让我们回顾一下(2019+)。

参数:值,例如truefalsenull是有效JSON(?)

事实:这些原始值是JSON 可解析的,但它们不是格式良好的 JSON 结构JSON 规范表明 JSON 建立在两种结构上:名称/值对(对象)的集合或值的有序列表(数组)。

论点:不应使用异常处理来执行预期的操作。
(这是一条有 25 多个赞成票的评论!)

事实:不!使用 try/catch 绝对是合法的,尤其是在这种情况下。否则,你需要做很多字符串分析的工作,比如标记/正则表达式操作;这将有可怕的表现。

hasJsonStructure()

如果您的目标是检查某些数据/文本是否具有正确的 JSON 交换格式,这将非常有用。

function hasJsonStructure(str) {
    if (typeof str !== 'string') return false;
    try {
        const result = JSON.parse(str);
        const type = Object.prototype.toString.call(result);
        return type === '[object Object]' 
            || type === '[object Array]';
    } catch (err) {
        return false;
    }
}

用法:

hasJsonStructure('true')             // —» false
hasJsonStructure('{"x":true}')       // —» true
hasJsonStructure('[1, false, null]') // —» true

safeJsonParse()

如果您想在将某些数据解析为 JavaScript 值时小心谨慎,这将非常有用。

function safeJsonParse(str) {
    try {
        return [null, JSON.parse(str)];
    } catch (err) {
        return [err];
    }
}

用法:

const [err, result] = safeJsonParse('[Invalid JSON}');
if (err) {
    console.log('Failed to parse JSON: ' + err.message);
} else {
    console.log(result);
}
您链接到 JSON 规范说明如下:“JSON 文本是由符合 JSON 值语法的 Unicode 代码点形成的令牌序列。” 和“JSON 值可以是对象、数组、数字、字符串、true、false 或 null。” - 您是如何得出 JSON 只能是根级别的对象或数组的结论的?我在规范中看不到这一点,也没有关于“格式良好的 JSON 结构”的任何内容
2021-03-13 23:17:02
读第二段与开始“JSON是建立在两个结构......” @ json.org或第4和第5段ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf
2021-03-17 23:17:02
好的,所以我想我们同意。根据规范,原语是有效的 JSON,但不是“结构”。没关系。但是,您说“参数:诸如 true、false、null 之类的值是有效的 JSON (?)。事实:是和否!” - 事实是符合规范的 ARE 有效 JSON。关于它们是否有用的意见与该事实无关。
2021-03-19 23:17:02
json.org 仅供参考。阅读您链接的规范不支持您的建议。该规范提到 RFC 8259 作为最新的 RFC。查看仅包含值的有效 JSON 文本示例tools.ietf.org/html/rfc8259#section-13 - RFC 8259 旨在解决可能的歧义和混淆,就像这样。
2021-03-27 23:17:02
再次阅读答案。我是说诸如原语(即 RFC 示例中的文本值)之类的值不是 JSON“结构”。没有歧义。您可以将它们解析为 JSON,这样做是有效的。但它们不是结构化数据。JSON 主要被发明为一种交换格式 » 用于结构化数据 » 可以是对象或数组。
2021-04-12 23:17:02

如果服务器用 JSON 响应,那么它会有一个application/json内容类型,如果它用纯文本消息响应,那么它应该有一个text/plain内容类型。确保服务器以正确的内容类型响应并测试它。

这是错误的,还有许多其他与 json 兼容的媒体类型。此外overrideMimeType可以覆盖内容类型标头。
2021-03-22 23:17:02

如果响应是 JSON,则使用jQuery $.ajax()响应将具有responseJSON属性,可以这样测试:

if (xhr.hasOwnProperty('responseJSON')) {}
我怀疑这真的是大多数人正在寻找的答案,甚至可能是 OP
2021-03-13 23:17:02
这比使用 try catch 块要优雅得多
2021-03-13 23:17:02