Check for valid JSON object or string

I was looking for a JavaScript code that will check, if passed variable is a valid JSON, no matter, if it is an object or string. I failed with that, because I only found separate solutions for either object or string. Though its authors claimed that they work fine for both objects and strings, as simple check found out this is not true.

Validate JSON passed as an object (jQuery-based solution)

First I found this answer to this question:

function isJSON(data)
{
    var isJson = false;
    
    try
    {
        //This works with JSON string and JSON object, not sure about others.
        var json = $.parseJSON(data);
        isJson = (typeof(json) === 'object');
    }
    catch (ex) {console.error('data is not JSON');}
    
    return isJson;
}

I test it and it works fine for me (JSON object from PHP’s json_encode passes as valid), but it doesn’t work for an example string: { "Id": 1, "Name": "Coke" }. It returns false.

Validate JSON passed as an object (non-jQuery-based solution)

Above solution uses jQuery’s parseJSON function. If someone want a function that does not require jQuery, then may look to this answer for this question.

Here is a code, a bit updated by me:

function IsJsonString(json)
{
    var str = json.toString();
    
    try
    {
        JSON.parse(str);
    }
    catch (e)
    {
        return false;
    }
    
    return true;
}

It uses parse function form JSON library. But, again, it works fine for JSON object, but it doesn’t work for any string, returning false.

Validate JSON passed as a string

Finally I found a function that (after small corrections) is able to check validity of JSON passed as a string.

Here you have final version, corrected by me:

jQuery.isJSON = function(data)
{
    var str = data.toString();

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

    return (/^[],:{}s]*$/).test(str);
}

I removed some stupid bugs from original one. I.e. there is not blank() function defined for strings. And I have no idea, how author would like to use object-oriented approach (var str = this) on non-object function definition?

Unfortunately, it fails completely on objects containing JSON. I don’t know why, but even after stringifying JSON object, this function return false on perfectly valid JSON objects.

This is declared as jQuery extension, but you can of course use it easily in non-jQuery environment, by removing jQuery.isJSON = and use direct function call.

Conclusions

Some final remarks:

1. Many people asks/looks for function that will work for objects (so third goes hell), but will not use try/catch (first two go hell). Look for other answers in question, to which I posted links here and you should find such. Some suggested using JSON2 library instead.

2. Never, ever use or even think about any solution that uses eval(). Eval() is evil! Eval() is bad! Any use of eval() is the beginning of all hell! Always remember words said by Rasmus Lerdorf, the creator of PHP:

If eval() is the answer, you’re almost certainly asking the wrong question!

This is, how it looks now. Since I’m using only JSON-like objects, not strings, and since I’m using jQuery, I decided to use first approach. But it would be very nice, if someone could contribute solution that would work 100% correct for both objects and strings containg JSON.

Leave a Reply