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

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

这就是我想要的:

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

当前回答

使用JSON.parse

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

其他回答

这是伯恩的回答中有一些小改动的密码。 由于JSON.parse(number)工作正常,没有任何异常,所以添加了isNaN。

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

让我们回顾一下(2019年以上)。

参数:true, false, null等值是有效的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);
}

我喜欢最好的答案,但如果它是一个空字符串,它返回真。这里有一个解决方案:

function isJSON(MyTestStr){
    try {
        var MyJSON = JSON.stringify(MyTestStr);
        var json = JSON.parse(MyJSON);
        if(typeof(MyTestStr) == 'string')
            if(MyTestStr.length == 0)
                return false;
    }
    catch(e){
        return false;
    }
    return true;
}

我认为像下面的方法应该做的工作,它返回解析的JSON(在有效的JSON的情况下),所以你不需要调用JSON。解析了。

const tryParseJSON = (s) => {
    if (!s) return false;

    try {
        var o = JSON.parse(s);
        if (o && typeof o === "object") return o;
    }
    catch (e) { }

    return false;
};

警告:对于依赖JSON的方法。parse -数组和引号括起来的字符串也会被传递。console.log (JSON.parse ([3]), JSON.parse (" \ uD800 ")))

为了避免所有非对象JSON原语(boolean, null, array, number, string),我建议使用以下方法:

/* Validate a possible object ie. o = { "a": 2 } */
const isJSONObject = (o) => 
  !!o && (typeof o === 'object') && !Array.isArray(o) && 
  (() => { try { return Boolean(JSON.stringify(o)); } catch { return false } })()

/* Validate a possible JSON object represented as string ie. s = '{ "a": 3 }' */
function isJSONObjectString(s) {
    try {
        const o = JSON.parse(s);
        return !!o && (typeof o === 'object') && !Array.isArray(o)
    } catch {
        return false
    }
}

代码的解释

!!o -非假(不包括null,它注册为'object'类型) (typeof o === 'object') -不包括布尔值,数字和字符串 Array.isArray(o) -排除数组(注册为'object'类型的数组) 试一试……JSON。stringify / JSON。parse -请求JavaScript引擎判断是否有效的JSON

为什么不使用hasJsonStructure()答案?

依赖toString()不是一个好主意。这是因为不同的JavaScript引擎可能返回不同的字符串表示形式。一般来说,依赖于此的方法在不同的环境中可能会失败,或者在引擎更改字符串结果后可能会失败

为什么捕获异常不是破解?

有人提出,通过捕获异常来确定某个东西的有效性从来都不是正确的方法。这通常是一个好建议,但也不总是这样。在这种情况下,异常捕获可能是最好的方法,因为它依赖于JavaScript引擎验证JSON数据的实现。

依赖JS引擎提供了以下优势:

更彻底,随着JSON规范的变化不断更新 可能运行得更快(因为它是较低级别的代码)

当有机会依赖JavaScript引擎时,我建议这样做。在这种情况下尤其如此。尽管捕获异常可能有点笨拙,但实际上只是处理外部方法的两种可能返回状态。