我有一个简单的AJAX调用,服务器将返回包含有用数据的JSON字符串或PHP函数产生的错误消息字符串mysql_error()
。如何测试此数据是JSON字符串还是错误消息。
最好使用一个称为的函数isJSON
,就像您可以使用该函数instanceof
来测试某物是否为数组一样。
这就是我要的:
if (isJSON(data)){
//do some data stuff
}else{
//report the error
alert(data);
}
我有一个简单的AJAX调用,服务器将返回包含有用数据的JSON字符串或PHP函数产生的错误消息字符串mysql_error()
。如何测试此数据是JSON字符串还是错误消息。
最好使用一个称为的函数isJSON
,就像您可以使用该函数instanceof
来测试某物是否为数组一样。
这就是我要的:
if (isJSON(data)){
//do some data stuff
}else{
//report the error
alert(data);
}
Answers:
使用JSON.parse
function isJson(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
JSON.parse(1234)
OR JSON.parse(0)
OR JSON.parse(false)
OR JSON.parse(null)
all将不会引发Exception并将返回true!不要使用此答案
1234
,0
,false
,和null
都是有效的JSON值。如果您想要一个谓词来测试JSON是否代表一个对象,则需要做更多的事情。
JSON.parse
进行了大量计算以解析该字符串,如果成功,则为您提供json对象,但是您正在丢弃某些用户可能想要使用的结果。那似乎不好。我将改为return {value: JSON.parse(str), valid: true};
在catch块return {value: str, valid: false};
中将函数名称更改为tryParse()
。
此代码是JSON.parse(1234)
or JSON.parse(0)
或JSON.parse(false)
or JSON.parse(null)
all将返回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;
}
测试结果:
return (typeof suspect === "object" && suspect !== null);
让我们回顾一下(2019年以上)。
参数:值,例如
true
,false
,null
是有效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;
}
}
用法:
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);
}
当使用jQuery $.ajax()
响应时,responseJSON
如果响应是JSON,则将具有该属性,可以这样检查:
if (xhr.hasOwnProperty('responseJSON')) {}
我喜欢最佳答案,但是如果它是一个空字符串,则返回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;
}
好吧...这取决于您接收数据的方式。我认为服务器正在以JSON格式的字符串响应(例如在PHP中使用json_encode())。如果您使用的是JQuery发布,并将响应数据设置为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',
});
response
是空的,它将转到success
:'(
可能有一些测试可以做,例如,如果您知道返回的JSON总是会被包围{
,}
那么您可以测试这些字符或其他一些hacky方法。或者您可以使用json.org JS库尝试解析它并测试它是否成功。
但是,我建议采用另一种方法。如果调用成功,您的PHP脚本当前返回JSON,否则返回JSON。为什么不总是返回JSON?
例如
成功呼叫:
{ "status": "success", "data": [ <your data here> ] }
错误呼叫:
{ "status": "error", "error": "Database not found" }
这将使编写客户端JS变得更加容易-您要做的就是检查“状态”成员并相应地执行操作。
我仅用两行来执行该操作:
var isValidJSON = true;
try { JSON.parse(jsonString) } catch { isValidJSON = false }
就这样!
但是请记住有两个陷阱:
1. JSON.parse(null)
返回null
2.可以使用JSON.parse()
method 解析任何数字或字符串。
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
[
和来指定数组]
。例如,[1, 2, 3]
是一个数字数组。["a", "b", "c"]
是一个字符串数组。并且[{"a":1}, {"b":2}]
是一个JSON数组。您的jsfiddle工作似乎非常有用!
JSON.parse
。谁能建议不使用try避免该错误?
jsfiddle
由于测试3没有有效的JSON表达式,因此您的应用程序将引发错误。因此,try-catch
必须使用a来捕获该错误并评估任何错误,因为在像上面的Test 3一样进行解析时,表达式不是JSON:try { JSON.parse(data3) } catch(e) { isValidJSON = false }
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);
}
警告:对于依赖的方法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
}
}
代码说明
为什么不使用hasJsonStructure()答案?
依靠 toString()
不是一个好主意。这是因为不同的JavaScript引擎可能返回不同的字符串表示形式。通常,依赖此方法的方法可能在不同的环境中失败,或者如果引擎更改了字符串结果,则以后可能会失败
为什么捕获异常不是黑客?
人们提出,捕获异常来确定某项内容的有效性绝不是正确的方法。通常这是一个很好的建议,但并非总是如此。在这种情况下,捕获异常可能是最好的方法,因为它依赖JavaScript引擎对JSON数据进行验证的实现。
依靠JS引擎具有以下优点:
如果有机会依靠JavaScript引擎,我建议您这样做。在这种情况下尤其如此。虽然可能会感觉捕获异常麻烦,但实际上您只是在处理来自外部方法的两个可能的返回状态。
这是对Bourne的答案进行一些小的修改的代码。由于JSON.parse(number)正常工作,没有任何异常,因此添加了isNaN。
function isJson(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return isNaN(str);
}
所有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
{ someValue }
会自动通过验证,那就不好了。
我建议在打字稿模式下:
export function stringify(data: any): string {
try {
return JSON.stringify(data)
} catch (e) {
return 'NOT_STRINGIFIABLE!'
}
}
我使用了这个(混合了不同的答案,但是无论如何):
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('-----------------')
您可以尝试以下方法,因为它也可以验证数字,空值,字符串,但是上面标记的答案不能正常工作,这只是上述功能的一种解决方法:
function isJson(str) {
try {
const obj = JSON.parse(str);
if (obj && typeof obj === `object`) {
return true;
}
} catch (err) {
return false;
}
return false;
}
除了先前的答案,如果您需要验证“ {}”之类的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
eval()
如果返回undefined
则不是JSON