How to test if a string is JSON or not?
I have a simple AJAX call, and the server will return either a JSON string with useful data or an error message string produced by the PHP function mysql_error()
. How can I test whether this data is a JSON string or the error message.
It would be nice to use a function called isJSON
just like you can use the function instanceof
to test if something is an Array.
This is what I want:
if (isJSON(data)){
//do some data stuff
}else{
//report the error
alert(data);
}
Use JSON.parse
function isJson(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
This code is JSON.parse(1234)
or JSON.parse(0)
or JSON.parse(false)
or JSON.parse(null)
all will return true.
function isJson(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
So I rewrote code in this way:
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;
}
Testing result:
isJson test result
Let's recap this (for 2019+).
Argument: Values such as
true
,false
,null
are valid JSON (?)
FACT: These primitive values are JSON-parsable but they are not well-formed JSON structures. JSON specification indicates JSON is built on on two structures: A collection of name/value pair (object) or an ordered list of values (array).
Argument: Exception handling shouldn't be used to do something expected.
(This is a comment that has 25+ upvotes!)
FACT: No! It's definitely legal to use try/catch, especially in a case like this. Otherwise, you'd need to do lots of string analysis stuff such as tokenizing / regex operations; which would have terrible performance.
hasJsonStructure()
This is useful if your goal is to check if some data/text has proper JSON interchange format.
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;
}
}
Usage:
hasJsonStructure('true') // —» false
hasJsonStructure('{"x":true}') // —» true
hasJsonStructure('[1, false, null]') // —» true
safeJsonParse()
And this is useful if you want to be careful when parsing some data to a JavaScript value.
function safeJsonParse(str) {
try {
return [null, JSON.parse(str)];
} catch (err) {
return [err];
}
}
Usage:
const [err, result] = safeJsonParse('[Invalid JSON}');
if (err) {
console.log('Failed to parse JSON: ' + err.message);
} else {
console.log(result);
}
If the server is responding with JSON then it would have an application/json
content-type, if it is responding with a plain text message then it should have a text/plain
content-type. Make sure the server is responding with the correct content-type and test that.
When using jQuery $.ajax()
the response will have the responseJSON
property if the response was JSON, this can be tested like this:
if (xhr.hasOwnProperty('responseJSON')) {}