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

jef*_*ind 147 javascript mysql json

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

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

这就是我要的:

if (isJSON(data)){
    //do some data stuff
}else{
    //report the error
    alert(data);
}
Run Code Online (Sandbox Code Playgroud)

Bou*_*rne 273

使用JSON.parse

function isJson(str) {
    try {
        JSON.parse(str);
    } catch (e) {
        return false;
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

  • 不应使用异常处理来执行预期的操作. (47认同)
  • `JSON.parse(1234)`或``JSON.parse(0)`或``JSON.parse(false)`或``JSON.parse(null)`都不会引发异常并返回true !! 不要使用这个答案 (37认同)
  • `JSON.parse`执行大量计算来解析字符串,如果成功则给你json对象,但是你丢弃了一些用户可能想要使用的结果.这似乎并不好.我改为`return {value:JSON.parse(str),valid:true};`并且在catch块`return {value:str,valid:false};`..我会改变函数名到`tryParse()`. (19认同)
  • @ Zalaboza`1234`,`0`,`false`和`null`都是有效的JSON值.如果你想要一个测试JSON代表一个对象的谓词,你需要做更多的事情. (16认同)
  • @luisZavaleta然后你建议作为一种方法 (6认同)

kub*_*ho_ 63

此代码JSON.parse(1234)JSON.parse(0)JSON.parse(false)JSON.parse(null)都将返回true.

function isJson(str) {
    try {
        JSON.parse(str);
    } catch (e) {
        return false;
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

所以我用这种方式重写了代码:

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;
}
Run Code Online (Sandbox Code Playgroud)

测试结果:

isJson测试结果

  • 干得好!您的最后一个if语句可以简化为简单的return语句,例如:`return(typeof怀疑者===“对象” &&可疑!== null);` (4认同)

Onu*_*rım 23

让我们回顾一下(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;
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

hasJsonStructure('true')             // —» false
hasJsonStructure('{"x":true}')       // —» true
hasJsonStructure('[1, false, null]') // —» true
Run Code Online (Sandbox Code Playgroud)

safeJsonParse()

如果在将某些数据解析为JavaScript值时要格外小心,这将很有用。

function safeJsonParse(str) {
    try {
        return [null, JSON.parse(str)];
    } catch (err) {
        return [err];
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

const [err, result] = safeJsonParse('[Invalid JSON}');
if (err) {
    console.log('Failed to parse JSON: ' + err.message);
} else {
    console.log(result);
}
Run Code Online (Sandbox Code Playgroud)

  • 再次阅读答案。我是说诸如基元之类的值(即 RFC 示例中的文本值)不是 JSON“结构”。没有任何歧义。您可以将它们解析为 JSON,这样做是有效的。但它们不是结构化数据。JSON 主要是作为一种交换格式而发明的,用于结构化数据,可以是对象或数组。 (2认同)
  • 好的,所以我想我们同意。根据规范,基元是有效的 JSON,但不是“结构”。没关系。但是,你说“参数:true、false、null 等值是有效的 JSON (?)。事实:是和否!” - 事实上,根据规范,ARE 是有效的 JSON。关于它们是否有用的意见与该事实无关。 (2认同)

Que*_*tin 20

如果服务器使用JSON进行响应,那么它将具有application/json内容类型,如果它使用纯文本消息进行响应,那么它应该具有text/plain内容类型.确保服务器使用正确的内容类型进行响应并对其进行测试.

  • 这是错误的,还有许多其他json兼容的mediatypes.此外,`overrideMimeType`可以覆盖内容类型头. (3认同)

rém*_*émy 11

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

if (xhr.hasOwnProperty('responseJSON')) {}
Run Code Online (Sandbox Code Playgroud)

  • 这是我怀疑的确是大多数人都在寻找的答案,甚至可能是OP (2认同)

ZER*_*ER0 7

var parsedData;

try {
    parsedData = JSON.parse(data)
} catch (e) {
    // is not a valid JSON string
}
Run Code Online (Sandbox Code Playgroud)

但是,我会建议您,您的 http 调用/服务应始终以相同格式返回数据。因此,如果您有错误,那么您应该有一个包含此错误的 JSON 对象:

{"error" : { "code" : 123, "message" : "Foo not supported" } } 
Run Code Online (Sandbox Code Playgroud)

并且可能使用 5xx 代码以及 HTTP 状态。


小智 6

我喜欢最好的答案,但如果它是一个空字符串,则返回true.所以这是一个修复:

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;
}
Run Code Online (Sandbox Code Playgroud)


mdm*_*mdm 5

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

不过,我建议采用不同的方法。如果调用成功,您的 PHP 脚本当前将返回 JSON,如果调用失败,则返回其他内容。为什么不总是返回 JSON?

例如

调用成功:

{ "status": "success", "data": [ <your data here> ] }
Run Code Online (Sandbox Code Playgroud)

错误调用:

{ "status": "error", "error": "Database not found" }
Run Code Online (Sandbox Code Playgroud)

这将使编写客户端 JS 变得更加容易 - 您所要做的就是检查“状态”成员和相应的操作。


Luc*_*ssi 5

嗯......这取决于您接收数据的方式.我认为服务器正在使用JSON格式化字符串进行响应(例如,在PHP中使用json_encode()).如果您正在使用JQuery post并将响应数据设置为JSON格式,并且它是格式错误的JSON,则会产生错误:

$.ajax({
  type: 'POST',
  url: 'test2.php',
  data: "data",
  success: function (response){

        //Supposing x is a JSON property...
        alert(response.x);

  },
  dataType: 'json',
  //Invalid JSON
  error: function (){ alert("error!"); }
});
Run Code Online (Sandbox Code Playgroud)

但是,如果您将类型响应用作文本,则需要使用$ .parseJSON.根据jquery站点:"传入格式错误的JSON字符串可能会导致抛出异常".因此,您的代码将是:

$.ajax({
  type: 'POST',
  url: 'test2.php',
  data: "data",
  success: function (response){

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

  },
  dataType: 'text',
});
Run Code Online (Sandbox Code Playgroud)


efk*_*kan 5

我只使用 2 行来执行该操作:

var isValidJSON = true;
try { JSON.parse(jsonString) } catch { isValidJSON = false }
Run Code Online (Sandbox Code Playgroud)

就这样!

但请记住有 2 个陷阱:
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
Run Code Online (Sandbox Code Playgroud)


Dev*_*ain 5

这是对 Bourne 的答案进行了一些细微修改的代码。由于 JSON.parse(number) 工作正常,没有任何异常,因此添加了 isNaN。

function isJson(str) {
    try {
        JSON.parse(str);
    } catch (e) {
        return false;
    }
    return isNaN(str);
}
Run Code Online (Sandbox Code Playgroud)