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

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

这就是我想要的:

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

当前回答

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

其他回答

除了前面的答案,如果你需要验证一个JSON格式,如“{}”,你可以使用以下代码:

const validateJSON = (str) => {
  try {
    const json = JSON.parse(str);
    if (Object.prototype.toString.call(json).slice(8,-1) !== 'Object') {
      return false;
    }
  } catch (e) {
    return false;
  }
  return true;
}

用法示例:

validateJSON('{}')
true
validateJSON('[]')
false
validateJSON('')
false
validateJSON('2134')
false
validateJSON('{ "Id": 1, "Name": "Coke" }')
true

我用了这个(有点混合了不同的答案,但不管怎样):

const isJSON = str => { If (typeof STR === 'string'){ 尝试{ JSON.parse (str) 还真 }捕捉(e) { } } 返回假 } [null, undefined, false, true, [], {}, ”,“asdf ', '{}', '[]', "{\" abc \”:2}”、“{\“abc \”,\“2 \“}”) .map(el => { console.log(' [>${el}<] - ${isJSON(el)} ') }) console.log ('-----------------')

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

所有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

我只用了2行代码来执行:

var isValidJSON = true;
try { JSON.parse(jsonString) } catch { isValidJSON = false }

这是所有!

但要记住有两个陷阱: 1. JSON.parse(null)返回null 2. 任何数字或字符串都可以用JSON.parse()方法解析。 JSON.parse("5")返回5 JSON.parse(5)返回5

让我们来玩一下代码:

// TEST 1
var data = '{ "a": 1 }'

// Avoiding 'null' trap! Null is confirmed as JSON.
var isValidJSON = data ? true : false
try { JSON.parse(data) } catch(e) { isValidJSON = false }

console.log("data isValidJSON: ", isValidJSON);
console.log("data isJSONArray: ", isValidJSON && JSON.parse(data).length ? true : false);

Console outputs:
data isValidJSON:  true
data isJSONArray:  false


// TEST 2
var data2 = '[{ "b": 2 }]'

var isValidJSON = data ? true : false
try { JSON.parse(data2) } catch(e) { isValidJSON = false }

console.log("data2 isValidJSON: ", isValidJSON);
console.log("data2 isJSONArray: ", isValidJSON && JSON.parse(data2).length ? true : false);

Console outputs:
data2 isValidJSON:  true
data2 isJSONArray:  true


// TEST 3
var data3 = '[{ 2 }]'

var isValidJSON = data ? true : false
try { JSON.parse(data3) } catch(e) { isValidJSON = false }

console.log("data3 isValidJSON: ", isValidJSON);
console.log("data3 isJSONArray: ", isValidJSON && JSON.parse(data3).length ? true : false);

Console outputs:
data3 isValidJSON:  false
data3 isJSONArray:  false


// TEST 4
var data4 = '2'

var isValidJSON = data ? true : false
try { JSON.parse(data4) } catch(e) { isValidJSON = false }

console.log("data4 isValidJSON: ", isValidJSON);
console.log("data4 isJSONArray: ", isValidJSON && JSON.parse(data4).length ? true : false);


Console outputs:
data4 isValidJSON:  true
data4 isJSONArray:  false


// TEST 5
var data5 = ''

var isValidJSON = data ? true : false
try { JSON.parse(data5) } catch(e) { isValidJSON = false }

console.log("data5 isValidJSON: ", isValidJSON);
console.log("data5 isJSONArray: ", isValidJSON && JSON.parse(data5).length ? true : false);


Console outputs:
data5 isValidJSON:  false
data5 isJSONArray:  false

// TEST 6
var data6; // undefined

var isValidJSON = data ? true : false
try { JSON.parse(data6) } catch(e) { isValidJSON = false }

console.log("data6 isValidJSON: ", isValidJSON);
console.log("data6 isJSONArray: ", isValidJSON && JSON.parse(data6).length ? true : false);

Console outputs:
data6 isValidJSON:  false
data6 isJSONArray:  false