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

时间:2012-03-21 12:38:58

标签: javascript mysql json

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

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

这就是我想要的:

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

22 个答案:

答案 0 :(得分:241)

使用JSON.parse

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

答案 1 :(得分:47)

此代码为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;
}

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

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;
}

测试结果:

isJson test result

答案 2 :(得分:21)

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

答案 3 :(得分:11)

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

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

答案 4 :(得分:9)

让我们回顾一下(适用于2018年以上)。

  

参数:诸如truefalsenull之类的值是有效的JSON(?)

事实:是,不是!这些原始值是 JSON可解析的,但不是格式良好的JSON结构JSON specification表示JSON建立在两个结构上:名称/值对(对象)或值的有序列表(数组)的集合。

  

参数:不应使用异常处理来完成预期的操作。
  (这是具有25个以上投票的评论!)

事实:否!使用try / catch绝对合法,尤其是在这种情况下。否则,您需要做很多字符串分析工作,例如标记化/正则表达式操作。会有糟糕的表现。

hasJsonStructure()

如果您的目标是检查某些数据/文本是否具有正确的JSON交换格式,这将很有用。

function hasJsonStructure(str) {
    if (typeof str !== 'string') return false;
    try {
        const result = JSON.parse(str);
        return Object.prototype.toString.call(result) === '[object Object]' 
            || Array.isArray(result);
    } 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);
}

答案 5 :(得分: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;
}

答案 6 :(得分:5)

嗯......这取决于您收到数据的方式。我认为服务器正在响应JSON格式化 string(例如,在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!"); }
});

但是,如果您将类型响应用作文本,则需要使用$ .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',
});

答案 7 :(得分:4)

var parsedData;

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

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

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

也许可以使用5x代码和HTTP状态。

答案 8 :(得分:4)

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

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

E.g。

成功通话:

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

错误的电话:

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

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

答案 9 :(得分:2)

您可以尝试对其进行解码并捕获exception(原生或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);
}

答案 10 :(得分:2)

我只使用2行来执行:

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

这就是全部!

但请记住有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

答案 11 :(得分:2)

警告::对于依赖JSON.parse的方法-数组和引号引起来的字符串也将通过(即console.log(JSON.parse('[3]'), JSON.parse('"\uD800"'))

为避免所有非对象JSON原语(布尔,空,数组,数字,字符串),我建议使用以下内容:

/* 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,它注册为typeof'object')
  • (typeof o ==='object')-排除布尔值,数字和字符串
  • !Array.isArray(o)-排除数组(注册为typeof'object')
  • 尝试... JSON.stringify / JSON.parse -要求JavaScript引擎确定是否有效JSON

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

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

为什么捕获异常不是黑客?

有人提出,捕获异常来确定某项内容的有效性永远不是正确的方法。通常这是一个很好的建议,但并非总是如此。在这种情况下,捕获异常可能是最好的方法,因为它依赖JavaScript引擎对JSON数据进行验证的实现。

依靠JS引擎具有以下优点:

  1. 随着JSON规范的变化而更加全面,不断更新
  2. 可能运行得更快(因为它是较低级别的代码)

如果有机会依靠JavaScript引擎,我建议您这样做。在这种情况下尤其如此。尽管捕获异常可能会感觉,但是您实际上只是在处理来自外部方法的两个可能的返回状态。

答案 12 :(得分:1)

我使用了这个(混合了不同答案,但无论如何):

const isJSON = str => {
  if (typeof str === 'string'){
    try {
      JSON.parse(str)
      return true
    } catch(e){
    }
  }
  return false
}



[null, undefined, false, true, [], {}, 
 '', 'asdf', '{}', '[]', "{\"abc\": 2}","{\"abc\": \"2\"}"]
  .map(el => {
      console.log(`[>${el}<] - ${isJSON(el)}`)
})

console.log('-----------------')

答案 13 :(得分:1)

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

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

答案 14 :(得分:0)

对我来说,我只是通过 2 个正返回条件来做到这一点,

第一条件 - 检查两端是否为“{”和“}”

第二个条件 - 检查它是否可以被 JSON 解析

我是怎么做到的

const isJsonStringified = (value) => {
  try {
    const isObject = value.slice(0, 1) === '{' && value.slice(value.length - 1) === '}';
    if (typeof value === 'string' && isObject) {
      JSON.parse(value);
    } else {
      return false;
    }
  } catch (err) {
    return false;
  }
  return true;
};

欢迎:)

答案 15 :(得分:0)

如果你不介意zip

swift

lodash

答案 16 :(得分:0)

我认为像下面这样的方法应该可以完成这项工作,它返回解析的 JSON(在有效 JSON 的情况下),因此您不需要再次调用 JSON.parse

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

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

    return false;
};

答案 17 :(得分:0)

您可以尝试以下方法,因为它还可以验证数字,空值,字符串,但是上面标记的答案无法正常工作,这只是上述功能的解决方案:

function isJson(str) {
  try {
      const obj = JSON.parse(str);
      if (obj && typeof obj === `object`) {
        return true;
      }
    } catch (err) {
      return false;
    }
   return false;
}

答案 18 :(得分:0)

我建议使用打字稿模式:

export function stringify(data: any): string {
    try {
         return JSON.stringify(data)
    } catch (e) {
         return 'NOT_STRINGIFIABLE!'
    }
}

答案 19 :(得分:0)

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

答案 20 :(得分:-1)

除了之前的答案,如果您需要验证像“{}”这样的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

答案 21 :(得分:-2)

上面的答案还可以,但是JSON.parse据说很昂贵,因此您很可能希望保留经过解析的数据,以防万一它通过了,而不是再次进行解析。

function isJson(str) {
    if (typeof str !== "string" || `${str}`.length === 0) return [false, str];
    let json = "";
    let isValid = false;
    try {
        json = JSON.parse(str);
        isValid = true;
    } catch (e) {
        isValid = false
    }
    if (!json || typeof json !== "object") isValid = false;
    return [isValid, json]
};

//Usage
const [isValid, json] = isJson("[\"abc\", \"123\"]");
if(isValid) console.log(json);