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

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

这就是我想要的:

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

当前回答

除了前面的答案,如果你需要验证一个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

其他回答

导出函数isJsonString(value) { 尝试{ return typeof JSON.parse(value) === 'object'; } catch (e) { 返回错误; } }

这为我处理了大部分所需的情况!

我只用了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

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

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的方法。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引擎时,我建议这样做。在这种情况下尤其如此。尽管捕获异常可能有点笨拙,但实际上只是处理外部方法的两种可能返回状态。

你可以尝试解码它并捕获异常(本机或json2.js):

try {
  newObj = JSON.parse(myJsonString);
} catch (e) {
  console.log('Not JSON');
}

但是,我建议将响应始终设置为有效的JSON。如果你从你的MySQL查询中得到一个错误,简单地发送回JSON错误:

{"error":"The MySQL error string."}

然后:

if (myParsedJSON.error) {
  console.log('An error occurred: ' + myParsedJSON.error);
}