var jsonString = '{ "Id": 1, "Name": "Coke" }';
//should be true
IsJsonString(jsonString);
//should be false
IsJsonString("foo");
IsJsonString("<div>foo</div>")
解决方案不应包含try / catch。我们中有些人打开“打破所有错误”,他们不喜欢调试器打破那些无效的JSON字符串。
#1 楼
首先发表评论。问题是关于不使用try/catch
的问题。所有情况。在https://github.com/douglascrockford/JSON-js/blob/master/json2.js
有450行一个正则表达式,用于检查有效的JSON,例如:一个正则表达式替换(来自@Mrchief的评论)
评论
这只是检查代码是否可以安全使用eval。例如,以下字符串“ 2011-6-27”将通过该测试。
–SystemicPlural
11年7月27日在16:22
@SystemicPlural,是的,但是问题是关于不使用try / catch
–麦克风
13年7月25日在10:33
您无法使用JavaScript中的正则表达式来测试字符串是否为有效的JSON,因为JS正则表达式不支持让您这样做的必要扩展(递归正则表达式)。您的上述代码在“ {”上失败。
– Venge
2014年6月1日22:12
@Mic json2.js不再使用该简单检查(而是使用4阶段解析来确定有效JSON)。建议修改或删除您的答案。请注意,我认为“不使用try / catch作为检查JSON的唯一机制”没有任何错误。
– r
16年6月20日在18:21
仅仅因为它对他有帮助,并不意味着它对我们其余的人有帮助,而这些人在几年后也有同样的问题。
–麦凯
16年8月11日在17:36
#2 楼
使用像JSON.parse
这样的JSON解析器:function IsJsonString(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
评论
谢谢,但是我只是与团队一起使用,他们想要一些不使用try / catch的东西。问题和新标题一起被编辑。对于那个很抱歉。
–陈志
2010-09-14 15:26
@trejder:这样做是因为1不是字符串,请尝试使用“ 1”
– Purefan
2014年3月4日23:47
@Gumbo我的评论已经1.5岁了! :]我不记得了,我两周前在做什么,您问我是否记得那个项目? :] 没门... :]
– Trejder
2014年5月5日在9:25
这个答案的问题是,如果该字符串确实签出,并且您对其进行了解析,则将其解析两次。难道您不能在错误的分析中返回false,而在成功时返回该对象吗?
–致癌物质
16-2-29在0:05
@Carcigenicate您可以这样做。但是,JSON.parse(“ false”)的计算结果也为false。
–浓汤
16年1月1日在19:54
#3 楼
我知道我这个问题迟到3年了,但是我感觉有点迟疑了。 />我也更愿意同时返回解析后的JSON,因此调用代码不必再次调用
JSON.parse({something that isn't JSON})
。 :function tryParseJSON (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;
};
评论
在页面上的答案中,这是最可靠和可靠的。
–Jonline
2014年5月30日17:07
o && o!== null是多余的。
– Aleksei Matiushkin
2014年10月21日15:21
在typeof中使用三重等于总是返回一个字符串。 :)
– Hein Haraldson Berg
2014年12月3日在16:09
尽管是老文章,但我认为值得摆弄一个小提琴来演示您的答案@matth,请注意,对象将无效。您必须传递一个JSON字符串。我猜可能对任何入门者都派上用场。
–stackunderflow
16年5月25日在14:18
该函数应该返回undefined,而不是false,因为false是有效的json字符串,并且无法区分tryParseJSON(“ false”)和tryParseJSON(“ garbage”)
–备用字节
18-2-22在17:32
#4 楼
// vanillaJS
function isJSON(str) {
try {
return (JSON.parse(str) && !!str);
} catch (e) {
return false;
}
}
用法:
isJSON({})
将是false
,isJSON('{}')
将是true
。 > // 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;
用法:
Array
将是Object
,isAO({})
将是true
。评论
请注意,因为null会通过此验证。
–法尔扎德YZ
17年5月30日在7:33
返回!!(JSON.parse(str)&& str);应该阻止空值。我将用此代码更新答案。
–马查多
17年8月23日在20:08
这是最好的答案,因为它还允许您检查JSON是否已被对象化,从而不通过parse()测试,从而导致WTF。
–not2qubit
18-2-22在13:33
#5 楼
这是我的工作代码:function IsJsonString(str) {
try {
var json = JSON.parse(str);
return (typeof json === 'object');
} catch (e) {
return false;
}
}
评论
IsJsonString(null); //返回true。可以通过比较typeof str ==='string'来解决
–gramcha
19年11月26日在8:54
null表示对象的空值,所以从我的角度来看这看起来还不错...它可能不适用于您的特定情况,但实际上
–地狱宝贝
11月6日8:18
#6 楼
我使用了一种非常简单的方法来检查字符串是否是有效的JSON。function testJSON(text){
if (typeof text!=="string"){
return false;
}
try{
JSON.parse(text);
return true;
}
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,因为空变量的类型是object。
每次。 :)
评论
JSON.parse(null),JSON.parse(“ false”)不会引发错误,可能还有更多示例
– klodoma
18 Mar 15'在10:18
是的,您是对的,我忘了检查输入是否为字符串,如果执行此操作,则此输入为null的方法将返回false。但是“ false”输入是有效的JSON字符串。这将被解析为布尔值(false)。现在,我将代码修改为更准确。
–kukko
18 Mar 16 '18在8:36
#7 楼
在prototypeJS中,我们有isJSON方法。你可以试试看。甚至json也可能有帮助。"something".isJSON();
// -> false
"\"something\"".isJSON();
// -> true
"{ foo: 42 }".isJSON();
// -> false
"{ \"foo\": 42 }".isJSON();
评论
谢谢,但是我认为使用原型库执行此操作有点过分了。
–陈志
2010-09-14 15:29
您给出了四个示例,但只有三个结果。 “ {foo:42}”。isJSON()的结果是什么?如果我假设是假的(结果应该跟随函数文档),那么好的问题是,为什么它是假的? {foo:42}似乎是完全有效的JSON。
– Trejder
2012年9月29日上午9:58
@trejder不幸的是,JSON规范需要带引号的键。
– mikermcneil
2012年10月8日,下午1:27
并且“ 2002-12-15” .isJSON返回true,而JSON.parse(“ 2002-12-15”)则引发错误。
–ychaouche
2012年11月13日17:14
我认为,更好的答案是将该函数从原型库中提取出来并将其放在此处。特别是因为api.prototypejs.org/language/string/prototype/isjson是404。
– jcollum
13年5月28日在17:53
#8 楼
来自原型框架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);
}
所以这是可用于传递字符串对象的版本。 br />
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 }" ) )
评论
任何人都有用于比较所有这些答案的测试套件?我想看看这个是否正确。
–Lonnie Best
19年11月21日在18:58
@LonnieBest好点。我的2美分。我已经在生产中使用了多年,并且一直工作良好且执行时间合理。
– loretoparisi
19年11月21日在22:18
#9 楼
这个答案减少了trycatch语句的成本。放慢了我的代码的速度,因此我使用了简单的Regex来检查字符串(是否是可能的JSON字符串),而不会通过检查其语法来进行检查,然后使用常规方法通过使用JQuery解析字符串: />
if (typeof jsonData == 'string') {
if (! /^[\[|\{](\s|.*|\w)*[\]|\}]$/.test(jsonData)) {
return jsonData;
}
}
try {
jsonData = $.parseJSON(jsonData);
} catch (e) {
}
我将先前的代码包装在一个递归函数中,以解析嵌套的JSON响应。
评论
jQuery做什么JSON.parse()不做什么?
– ADJenks
19年4月18日在20:26
#10 楼
我想我知道您为什么要避免这种情况。但是也许尝试并抓住!==尝试并抓住。 ; o)这是我的脑海:var json_verify = function(s){ try { JSON.parse(s); return true; } catch (e) { return false; }};
所以您还可能弄脏JSON对象,例如: />
尽可能将其封装,否则不会因错误而中断。
#11 楼
这也是打字稿版本: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;
};
评论
Typescript不是javascript,但您的答案似乎是。
–Lonnie Best
19年11月21日在19:02
#12 楼
也许会有用: 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:字符串,对象,字符串,字符串
:对象,对象,字符串,字符串
#13 楼
isValidJsonString-检查有效的json字符串
JSON数据类型-字符串,数字,对象(JSON对象),数组,布尔值,空值
(https://www.json.org/json-en.html)
javascript中的虚假值-false,0,-0、0n,“,null,undefined,NaN
-(https://developer.mozilla.org/zh-CN/docs/Glossary/Falsy)
对于number,boolean,null和有效的json字符串都适用,不会引发任何错误。请参考以下示例
JSON.parse('[1,2,3]')// [1、2、3]
解析undefined,object,array时中断etc
它提供了Uncaught SyntaxError:JSON输入意外结束。请参考以下示例
JSON.parse({})
JSON.parse([])
JSON.parse(未定义)
JSON.parse(“ jack”)
q4312 078q
#14 楼
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")
}
#15 楼
我从开篇评论中推断出用例正在描述响应是HTML还是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代码并在同时。
评论
这种混合解决方案似乎是避免大多数非JSON情况下必须进行尝试捕获的有效方法。我喜欢您的方法的这一方面。
–Lonnie Best
19年11月21日在19:14
#16 楼
if(resp) {
try {
resp = $.parseJSON(resp);
console.log(resp);
} catch(e) {
alert(e);
}
}
希望这也对您有用
#17 楼
function get_json(txt)
{ var data
try { data = eval('('+txt+')'); }
catch(e){ data = false; }
return data;
}
如果有错误,则返回false。
如果没有错误,则返回json数据
评论
在问题中:“解决方案不应包含try / catch”。
–ddmps
13年6月6日在3:58
为什么?这是保证的方式...废弃将是愚蠢的!对不起,我不懂英语。我用谷歌翻译
–艾姆拉·唐塞尔(Emrah Tuncel)
2013年3月6日23:32
有趣。我希望看到JSON.parse与基于评估的解决方案的性能比较。但是,从安全性/注入角度看,这看起来很可怕。
–Lonnie Best
19年11月21日在19:41
#18 楼
您可以使用javascript eval()函数来验证其是否有效。例如
.org:
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字符串是可信任的,即您是从可信任的来源获得的。
编辑对于我的第一种解决方案,建议执行此操作。
为了保证json-ness。如果
JSON.parse
不是纯JSON,则eval将引发异常。评论
使用eval的第一个示例说“
foo
”是有效的JSON。在不同的浏览器中,它的工作方式可能有所不同,但似乎在FireFox中,eval()接受XML。
–马克·卢顿
2010-09-14 15:26
谢谢,但是我只是与团队一起使用,他们想要一些不使用try / catch的东西。问题和新标题一起被编辑。对于那个很抱歉。
–陈志
2010-09-14 15:26
@Mark Lutton,对象类型将不是JSON,而是XML Dom Document(我忘记了firefox中的确切类型是什么)。
– Buhake Sindi
2010-09-14 15:30
eval还接受有效的JavaScript,例如“ alert(5);”。以及单引号中的字符串,这不是有效的JSON。
–马克·卢顿
2010-09-14 15:48
这纯粹是评估。
–克里斯·贝克(Chris Baker)
13年11月19日在20:45
#19 楼
哦,您绝对可以使用try catch来检查其是否为有效的JSON在Firfox Quantom 60.0.1上进行了测试。使用该输出来验证字符串。听到一个例子。
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}')
#20 楼
在我的情况下,使用IsJsonString(str)
的函数JSON.parse(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());
}
});
示例输出:
#21 楼
对于喜欢“尝试”函数的.Net约定的人,这些函数返回布尔值并处理包含结果的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
});
#22 楼
如果您要处理来自AJAX(或XMLHttpRequest)调用的响应,对我有用的是检查响应内容类型并相应地解析或不解析该内容。#23 楼
我认为我会在一个实际示例的背景下添加我的方法。在处理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)
}
}
}
#24 楼
非常简单的单行代码(但采用Hacky方法) ID。我将其用于API,并期望结果以JSON或某些错误字符串的形式出现。
评论
是否有合理的理由不使用try?@NickT因为如果您在调试器中打开“打破所有错误”,它将打开。 Chrome现在可以选择解决未捕获的错误。
仅使用2行即可通过try catch检查它。 var isValidJSON = true;尝试{JSON.parse(jsonString)} catch {isValidJSON = false; }
尽管这行得通,但它却是极度混乱和糟糕的做法。尝试/捕获旨在实现特殊的行为和错误处理,而不是常规程序流程。
@Tasgall通常,是的。但是,如果try / catch方法比任何基于验证器的方法更高效,该怎么办?选择(有时明显)较慢的选项,只是因为另一种选择是“不良做法”? try / catch方法在功能上没有任何问题,因此没有理由不使用它。让新程序员开发出良好的编码标准很重要,但同样重要的是,不要盲目遵守常规准则,尤其是在准则使事情变得比原本需要困难的情况下。