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

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

这就是我想要的:

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

当前回答

数字和布尔值在json .parse()中被接受为有效的json,只需在解析前添加类型验证

function isJson(str) {

    if(!isNaN(str) || str.toString() == 'true' || str.toString() == 'false'){
        return false;
    }

    try {

        JSON.parse(str);

    } catch (e) {

        return false;

    }

    return true;

}

其他回答

var parsedData;

try {
    parsedData = JSON.parse(data)
} catch (e) {
    // is not a valid JSON string
}

但是,我建议你的http call / service应该总是以相同的格式返回一个数据。所以如果你有一个错误,那么你应该有一个JSON对象来包装这个错误:

{"error" : { "code" : 123, "message" : "Foo not supported" } } 

可能还会使用HTTP状态5xx代码。

你可以做一些测试,例如,如果你知道返回的JSON总是被{和}包围,那么你可以测试这些字符,或者其他一些hack方法。或者你可以使用json.org JS库来尝试解析它,并测试它是否成功。

然而,我建议另辟蹊径。如果调用成功,PHP脚本当前返回JSON,如果调用失败,则返回其他内容。为什么不总是返回JSON?

E.g.

成功的电话:

{ "status": "success", "data": [ <your data here> ] }

错误的电话:

{ "status": "error", "error": "Database not found" }

这将使您的客户端JS编写更容易-你所要做的就是检查“status”成员和相应的行为。

所有json字符串都以'{'或'['开头,并以相应的'}'或']'结尾,所以只需检查一下。

Angular.js是这样做的:

var JSON_START = /^\[|^\{(?!\{)/;
var JSON_ENDS = {
  '[': /]$/,
  '{': /}$/
};

function isJsonLike(str) {
    var jsonStart = str.match(JSON_START);
    return jsonStart && JSON_ENDS[jsonStart[0]].test(str);
}

https://github.com/angular/angular.js/blob/v1.6.x/src/ng/http.js

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

if (xhr.hasOwnProperty('responseJSON')) {}

让我们回顾一下(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);
}