如何检查一个字符串是否是有效的 JSON 字符串?

isJsonString('{ "Id": 1, "Name": "Coke" }')

应该是 true

isJsonString('foo')
isJsonString('<div>foo</div>')

应该是 false

我正在寻找一种不使用 try/catch的解决方案,因为我已经将调试器设置为“在所有错误上中断”,这会导致它在无效的 JSON 字符串上中断。

892312 次浏览

使用像JSON.parse这样的JSON解析器:

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

在原型JS中,我们有方法isJSON。你可以尝试一下。甚至json也可能有所帮助。

"something".isJSON();
// -> false
"\"something\"".isJSON();
// -> true
"{ foo: 42 }".isJSON();
// -> false
"{ \"foo\": 42 }".isJSON();
// -> true

您可以使用javascriptava()函数来验证它是否有效。

e. g.

var jsonString = '{ "Id": 1, "Name": "Coke" }';
var json;


try {
json = eval(jsonString);
} catch (exception) {
//It's advisable to always catch an exception since eval() is a javascript executor...
json = null;
}


if (json) {
//this is json
}

或者,您可以使用json.org中的JSON.parse函数:

try {
json = JSON.parse(jsonString);
} catch (exception) {
json = null;
}


if (json) {
//this is json
}

希望这有帮助。

警告eval()危险,如果有人添加了恶意JS代码,因为它会执行它。确保JSON字符串为值得信赖,即您从受信任的来源获得它。

编辑对于我的第一个解决方案,建议这样做。

 try {
json = eval("{" + jsonString + "}");
} catch (exception) {
//It's advisable to always catch an exception since eval() is a javascript executor...
json = null;
}

保证 json-ness。如果jsonString不是纯JSON,则评估将抛出异常。

首先是一个评论。问题是关于不使用try/catch
如果你不介意使用它,阅读下面的答案。 这里我们只是使用正则表达式检查JSON字符串,它在大多数情况下都可以工作,而不是所有情况。

看看https://github.com/douglascrockford/JSON-js/blob/master/json2.js中的450线

有一个正则表达式可以检查有效的JSON,类似于:

if (/^[\],:{}\s]*$/.test(text.replace(/\\["\\\/bfnrtu]/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {


//the json is ok


}else{


//the json is not ok


}

编辑:新版本的json2.js进行了比上面更高级的解析,但仍然基于正则表达式替换(来自@毛主席的评论

也许它会有用:

    function parseJson(code)
{
try {
return JSON.parse(code);
} catch (e) {
return code;
}
}
function parseJsonJQ(code)
{
try {
return $.parseJSON(code);
} catch (e) {
return code;
}
}


var str =  "{\"a\":1,\"b\":2,\"c\":3,\"d\":4,\"e\":5}";
alert(typeof parseJson(str));
alert(typeof parseJsonJQ(str));
var str_b  = "c";
alert(typeof parseJson(str_b));
alert(typeof parseJsonJQ(str_b));

输出:

IE7:字符串,对象,字符串,字符串

CHROME:对象、对象、字符串、字符串

function get_json(txt)
{  var data


try     {  data = eval('('+txt+')'); }
catch(e){  data = false;             }


return data;
}

如果有错误,返回false。

如果没有错误,则返回json数据

我知道我这个问题已经晚了三年,但我想插嘴。

虽然Gumbo的解决方案效果很好,但它不能处理一些没有为JSON.parse({something that isn't JSON})引发异常的情况

我也更喜欢同时返回解析的JSON,因此调用代码不必第二次调用JSON.parse(jsonString)

这似乎很适合我的需求:

/**
* If you don't care about primitives and only objects then this function
* is for you, otherwise look elsewhere.
* This function will return `false` for any valid json primitive.
* EG, 'true' -> false
*     '123' -> false
*     'null' -> false
*     '"I'm a string"' -> false
*/
function tryParseJSONObject (jsonString){
try {
var o = JSON.parse(jsonString);


// Handle non-exception-throwing cases:
// Neither JSON.parse(false) or JSON.parse(1234) throw errors, hence the type-checking,
// but... JSON.parse(null) returns null, and typeof null === "object",
// so we must check for that, too. Thankfully, null is falsey, so this suffices:
if (o && typeof o === "object") {
return o;
}
}
catch (e) { }


return false;
};

这个回答降低了try catch语句的代价。

我使用JQuery来解析JSON字符串,我使用trycats___语句来处理异常,但是抛出异常un-parsable字符串减慢了我的代码,所以我使用简单的Regex来检查字符串是否是一个可能的JSON字符串,而不必检查它的语法,然后我使用常规方式使用JQuery解析字符串:

if (typeof jsonData == 'string') {
if (! /^[\[|\{](\s|.*|\w)*[\]|\}]$/.test(jsonData)) {
return jsonData;
}
}


try {
jsonData = $.parseJSON(jsonData);
} catch (e) {


}

我将前面的代码包装在一个递归函数中以解析嵌套的JSON响应。

我使用了一个非常简单的方法来检查字符串是否是有效的JSON。

function testJSON(text){
if (typeof text!=="string"){
return false;
}
try{
var json = JSON.parse(text);
return (typeof json === 'object');
}
catch (error){
return false;
}
}

结果为有效的JSON字符串:

var input='["foo","bar",{"foo":"bar"}]';
testJSON(input); // returns true;

结果是一个简单的字符串;

var input='This is not a JSON string.';
testJSON(input); // returns false;

结果为一个对象:

var input={};
testJSON(input); // returns false;

输入为空的结果:

var input=null;
testJSON(input); // returns false;

最后一个返回false,因为空变量的类型是对象。

每次都这样:)

// vanillaJS
function isJSON(str) {
try {
return (JSON.parse(str) && !!str);
} catch (e) {
return false;
}
}

用法:isJSON({})将是falseisJSON('{}')将是true

要检查某物是否是ArrayObject解析 JSON):

// vanillaJS
function isAO(val) {
return val instanceof Array || val instanceof Object ? true : false;
}


// ES2015
var isAO = (val) => val instanceof Array || val instanceof Object ? true : false;

用法:isAO({})将是trueisAO('{}')将是false

从原型框架String.isJSON定义这里

/**
*  String#isJSON() -> Boolean
*
*  Check if the string is valid JSON by the use of regular expressions.
*  This security method is called internally.
*
*  ##### Examples
*
*      "something".isJSON();
*      // -> false
*      "\"something\"".isJSON();
*      // -> true
*      "{ foo: 42 }".isJSON();
*      // -> false
*      "{ \"foo\": 42 }".isJSON();
*      // -> true
**/
function isJSON() {
var str = this;
if (str.blank()) return false;
str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
return (/^[\],:{}\s]*$/).test(str);
}

所以这是可以用来传递字符串对象的版本

function isJSON(str) {
if ( /^\s*$/.test(str) ) return false;
str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
return (/^[\],:{}\s]*$/).test(str);
}

function isJSON(str) {
if ( /^\s*$/.test(str) ) return false;
str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
return (/^[\],:{}\s]*$/).test(str);
}


console.log ("this is a json",  isJSON( "{ \"key\" : 1, \"key2@e\" : \"val\"}" ) )


console.log("this is not a json", isJSON( "{ \"key\" : 1, \"key2@e\" : pippo }" ) )

我想我知道你为什么想避免这种情况。但也许可以尝试和捕捉!==尝试和捕捉。; o)这出现在我的脑海中:

var json_verify = function(s){ try { JSON.parse(s); return true; } catch (e) { return false; }};

所以你也可以脏剪辑到JSON对象,比如:

JSON.verify = function(s){ try { JSON.parse(s); return true; } catch (e) { return false; }};

由于这尽可能地封装,它可能不会在错误时中断。

var jsonstring='[{"ConnectionString":"aaaaaa","Server":"ssssss"}]';


if(((x)=>{try{JSON.parse(x);return true;}catch(e){return false}})(jsonstring)){


document.write("valide json")


}else{
document.write("invalide json")
}

我从开场白中推断,用例正在描述响应是超文本标记语言还是JSON。在这种情况下,当你收到JSON时,你可能应该在代码中的某个时候解析它并处理无效的JSON。除此之外,我想你希望浏览器通知你是否应该收到JSON但收到无效的JSON(通过代理的用户也会收到一些有意义的错误消息)!

因此,为JSON做一个完整的正则表达式是不必要的(根据我的经验,对于大多数用例来说都是如此)。

function (someString) {
// test string is opened with curly brace or machine bracket
if (someString.trim().search(/^(\[|\{){1}/) > -1) {
try { // it is, so now let's see if its valid JSON
var myJson = JSON.parse(someString);
// yep, we're working with valid JSON
} catch (e) {
// nope, we got what we thought was JSON, it isn't; let's handle it.
}
} else {
// nope, we're working with non-json, no need to parse it fully
}
}

这应该可以节省您必须异常处理有效的非JSON代码同时处理duff json。

这也是打字稿版本:

JSONTryParse(input: any) {
try {
//check if the string exists
if (input) {
var o = JSON.parse(input);


//validate the result too
if (o && o.constructor === Object) {
return o;
}
}
}
catch (e: any) {
}


return false;
};
if(resp) {
try {
resp = $.parseJSON(resp);
console.log(resp);
} catch(e) {
alert(e);
}
}

希望这对你也有效

哦,你绝对可以使用try catch来检查它是否是有效的JSON

在Firfox Quantom 60.0.1上测试

使用函数中的函数来测试JSON并使用该输出来验证字符串。听到一个例子。

    function myfunction(text){


//function for validating json string
function testJSON(text){
try{
if (typeof text!=="string"){
return false;
}else{
JSON.parse(text);
return true;
}
}
catch (error){
return false;
}
}


//content of your real function
if(testJSON(text)){
console.log("json");
}else{
console.log("not json");
}
}


//use it as a normal function
myfunction('{"name":"kasun","age":10}')

这是我的工作代码:

function IsJsonString(str) {
try {
var json = JSON.parse(str);
return (typeof json === 'object');
} catch (e) {
return false;
}
}

使用JSON.parse(str)的函数IsJsonString(str)在我的情况下不起作用。
我尝试验证GraphiQL的json输出,它总是返回false。幸运的是,isJSON效果更好:

var test = false;


$('body').on('DOMSubtreeModified', '.resultWrap', function() {


if (!test) {
var resultWrap = "{" + $('#graphiql .resultWrap').text().split("{").pop();
if isJSON(resultWrap) {test = !test;}
console.log(resultWrap);
console.log(resultWrap.isJSON());
}


});

示例输出:

THREE.WebGLRenderer 79
draw.js:170 {xxxxxxxxxx​
draw.js:170 false
draw.js:170 {xxxxxxxxxx ​
draw.js:170 false
draw.js:170 {xxxxxxxxxx ​
draw.js:170 false
draw.js:170 {xxxxxxxxxx ​
draw.js:170 false
draw.js:170 {​
draw.js:170 false
draw.js:170 {  "PI": 3.141592653589793,​
draw.js:170 false
draw.js:170 {  "PI": 3.141592653589793,  "time": 1570751209006,​
draw.js:170 false
draw.js:170 {  "PI": 3.141592653589793,  "time": 1570751209006,  "tick": 156,​
draw.js:170 false
draw.js:170 {  "PI": 3.141592653589793,  "time": 1570751209006,  "tick": 156,  "tickr": 1.56,​
draw.js:170 false
draw.js:170 {  "PI": 3.141592653589793,  "time": 1570751209006,  "tick": 156,  "tickr": 1.56,  "fps": 41.666666666666664,​
draw.js:170 false
draw.js:170 {  "PI": 3.141592653589793,  "time": 1570751209006,  "tick": 156,  "tickr": 1.56,  "fps": 41.666666666666664,  "width": 396.984,​
draw.js:170 false
draw.js:170 {  "PI": 3.141592653589793,  "time": 1570751209006,  "tick": 156,  "tickr": 1.56,  "fps": 41.666666666666664,  "width": 396.984,  "height": 327​
draw.js:170 false
draw.js:170 {  "PI": 3.141592653589793,  "time": 1570751209006,  "tick": 156,  "tickr": 1.56,  "fps": 41.666666666666664,  "width": 396.984,  "height": 327}​
draw.js:170 false
draw.js:170 {  "PI": 3.141592653589793,  "time": 1570751209006,  "tick": 156,  "tickr": 1.56,  "fps": 41.666666666666664,  "width": 396.984,  "height": 327}
draw.js:170 true


对于喜欢. net约定的“try”函数,它返回一个布尔值并处理包含结果的byref参数。如果你不需要out参数,你可以省略它,只使用返回值。

StringTests.js

  var obj1 = {};
var bool1 = '{"h":"happy"}'.tryParse(obj1); // false
var obj2 = {};
var bool2 = '2114509 GOODLUCKBUDDY 315852'.tryParse(obj2);  // false


var obj3 = {};
if('{"house_number":"1","road":"Mauchly","city":"Irvine","county":"Orange County","state":"California","postcode":"92618","country":"United States of America","country_code":"us"}'.tryParse(obj3))
console.log(obj3);

StringUtils.js

String.prototype.tryParse = function(jsonObject) {
jsonObject = jsonObject || {};
try {
if(!/^[\[{]/.test(this) || !/[}\]]$/.test(this)) // begin / end with [] or {}
return false; // avoid error handling for strings that obviously aren't json
var json = JSON.parse(this);
if(typeof json === 'object'){
jsonObject.merge(json);
return true;
}
} catch (e) {
return false;
}
}

ObjectUtils.js

Object.defineProperty(Object.prototype, 'merge', {
value: function(mergeObj){
for (var propertyName in mergeObj) {
if (mergeObj.hasOwnProperty(propertyName)) {
this[propertyName] = mergeObj[propertyName];
}
}
return this;
},
enumerable: false, // this is actually the default
});

如果您正在处理来自AJAX(或XMLHttpRequest)调用的响应,对我来说有效的是检查响应内容类型并相应地解析或不解析内容。

  • isValidJsonString-检查有效的json字符串

  • JSON数据类型-字符串、数字、对象(JSON对象)、数组、布尔值、空 (https://www.json.org/json-en.html

  • javascript中的false sy值-false,0,-0,0n,", null, untex, NaN -(https://developer.mozilla.org/en-US/docs/Glossary/Falsy

  • JSON.parse

    • 适用于数字、布尔值、null和有效的json字符串不会引发任何错误。请参考下面的示例

      • JSON.parse(2)//2
      • JSON.parse//null
      • JSON.parse(true)//true
      • JSON.parse('{"name":"jhamman";}') // {name:"jhamman"}
      • JSON.parse('[1,2,3]') // [1,2,3]
    • 解析未定义、对象、数组等时中断

      • 它给出了未捕获的语法错误:JSON输入的意外结束。请参考下面的示例
      • JSON.parse({})
      • JSON.parse([])
      • JSON.parse(未定义)
      • JSON.parse(“杰克”)
function isValidJsonString(jsonString){
    

if(!(jsonString && typeof jsonString === "string")){
return false;
}


try{
JSON.parse(jsonString);
return true;
}catch(error){
return false;
}


}


我想我会在一个实际示例的上下文中添加我的方法。我在处理从Memjs进出的值时使用类似的检查,因此即使保存的值可能是字符串、数组或对象,Memjs也需要一个字符串。该函数首先检查键/值对是否已经存在,如果存在,则进行预检查以确定在返回值之前是否需要解析:

  function checkMem(memStr) {
let first = memStr.slice(0, 1)
if (first === '[' || first === '{') return JSON.parse(memStr)
else return memStr
}

否则,调用回调函数来创建值,然后对结果进行检查以查看在进入Memjs之前是否需要对值进行字符串化,然后返回回调的结果。

  async function getVal() {
let result = await o.cb(o.params)
setMem(result)
return result


function setMem(result) {
if (typeof result !== 'string') {
let value = JSON.stringify(result)
setValue(key, value)
}
else setValue(key, result)
}
}

完整的代码如下。当然,这种方法假设进出的数组/对象格式正确(即像“{key:'testkey']”这样的事情永远不会发生,因为所有正确的验证都是在键/值对到达这个函数之前完成的)。而且你只在memjs中输入字符串,而不是整数或其他非对象/数组类型。

async function getMem(o) {
let resp
let key = JSON.stringify(o.key)
let memStr = await getValue(key)
if (!memStr) resp = await getVal()
else resp = checkMem(memStr)
return resp


function checkMem(memStr) {
let first = memStr.slice(0, 1)
if (first === '[' || first === '{') return JSON.parse(memStr)
else return memStr
}


async function getVal() {
let result = await o.cb(o.params)
setMem(result)
return result


function setMem(result) {
if (typeof result !== 'string') {
let value = JSON.stringify(result)
setValue(key, value)
}
else setValue(key, result)
}
}
}

只是保持简单

function isValidJsonString(tester) {
//early existing
if(/^\s*$|undefined/.test(tester) || !(/number|object|array|string|boolean/.test(typeof tester)))
{
return false;
};
//go ahead do you parsing via try catch
return true;


};

如果你不想在任何地方尝试/捕获,寻找一个单一的班轮,并且不介意使用异步函数:

const isJsonString = async str => ( await ((async v => JSON.parse(v))(str)).then(_ => true).catch(_ => false) );


await isJsonString('{ "Id": 1, "Name": "Coke" }'); // true
await isJsonString('foo'); // false
await isJsonString('<div>foo</div>'); // false

我去派对太晚了。这就是我最终做的。 使用快速正则表达式预检查可以大大提高性能

if(/^\s*(\{|\[)/.test(str)){
try{
JSON.parse(str)
// do something here, or return obj/true
}catch(e){
//  do nothing or return false
}
}

正则表达式将检查字符串是否以[{打开。 这将消除大多数错误案例(不是全部)。 下面是一个快速的性能测试https://jsbench.me/awl6fgn8jb/1

最坏的情况下,这可能比直接使用try慢10-15%,最坏的情况意味着所有字符串都是有效的json字符串。

最好的情况下,这比纯try快99%,最好的情况意味着所有字符串都是无效的json。

检查字符串是否有效json的最简单方法。

    const json = JSON.parse(string)


if (typeof json == "object") {
console.log("string is a valid json")
}else{
console.log("string is not a valid json")
}

如果你有疑问的值实际上是在字符串或在json已经使用这种方式

  function isStringified(jsonValue) { // use this function to check
try {
console.log("need to parse");
return JSON.parse(jsonValue);
} catch (err) {
console.log("not need to parse");


return jsonValue;
}
}

然后

  const json = isStringified(stringValue);


if (typeof json == "object") {
console.log("string is a valid json")
}else{
console.log("string is not a valid json")
}