84

My JavaScript sometimes crashes on this line:

var json = eval('(' + this.responseText + ')');

Crashes are caused when the argument of eval() is not JSON. Is there any way to check if the string is JSON before making this call?

I don't want to use a framework - is there any way to make this work using just eval()? (There's a good reason, I promise.)

Nick Heiner
  • 119,074
  • 188
  • 476
  • 699
  • You could attempt to JSON.parse() in a try/catch... if you get to catch, its not valid JSON markup. Of course, thats sorta inefficient, heh... Could you give me an example of the invalid JSON markup you're getting? – Warty Feb 22 '10 at 19:50
  • Possible duplicate of [How to check if a string is a valid JSON string in JavaScript without using Try/Catch](https://stackoverflow.com/questions/3710204/how-to-check-if-a-string-is-a-valid-json-string-in-javascript-without-using-try) – Donald Duck Jun 21 '19 at 15:47

8 Answers8

158

If you include the JSON parser from json.org, you can use its parse() function and just wrap it in a try/catch, like so:

try
{
   var json = JSON.parse(this.responseText);
}
catch(e)
{
   alert('invalid json');
}

Something like that would probably do what you want.

Ry-
  • 218,210
  • 55
  • 464
  • 476
brettkelly
  • 27,655
  • 8
  • 56
  • 72
22

Hers's the jQuery alternative...

try
{
  var jsonObject = jQuery.parseJSON(yourJsonString);
}
catch(e)
{
  // handle error 
}
RayLoveless
  • 19,880
  • 21
  • 76
  • 94
16

I highly recommend you use a javascript JSON library for serializing to and from JSON. eval() is a security risk which should never be used unless you are absolutely certain that its input is sanitized and safe.

With a JSON library in place, just wrap the call to its parse() equivalent in a try/catch-block to handle non-JSON input:

try
{
  var jsonObject = JSON.parse(yourJsonString);
}
catch(e)
{
  // handle error 
}
Håvard S
  • 23,244
  • 8
  • 61
  • 72
2

Maybe this helps: With this code, you can get directly your data…

<!DOCTYPE html>
<html>
<body>

<h3>Open console, please, to view result!</h3>
<p id="demo"></p>

<script>
var tryJSON = function (test) {
 try {
     JSON.parse(test);
 }
 catch(err) {
     // maybe you need to escape this… (or not)
     test = '"'+test.replace(/\\?"/g,'\\"')+'"';
 }
 eval('test = '+test);
 console.debug('Try json:', test);
};

// test with string…
var test = 'bonjour "mister"';
tryJSON(test);
// test with JSON…
var test = '{"fr-FR": "<p>Ceci est un texte en français !</p>","en-GB": "<p>And here, a text in english!</p>","nl-NL": "","es-ES": ""}';
tryJSON(test);
</script>

</body>
</html>
Armali
  • 18,255
  • 14
  • 57
  • 171
  • There are a lot of alternative ways to achieve the same result, using eval() is probably be the least appropriate one. – David Apr 26 '19 at 14:48
1

The problem with depending on the try-catch approach is that JSON.parse('123') = 123 and it will not throw an exception. Therefore, In addition to the try-catch, we need to check the type as follows:

function isJsonStr(str) {
    var parsedStr = str;
    try {
        parsedStr = JSON.parse(str);
    } catch (e) {
        return false;
    }
    return typeof parsedStr == 'object'
}
Hesham Yassin
  • 4,341
  • 2
  • 21
  • 23
0

Why you can't just check what is the response? It is more more efficient.

var result;

if (response.headers['Content-Type'] === 'application/json')
    result = JSON.parse(this.responseText);
else
    result = this.responseText;

screen1

ADM-IT
  • 3,719
  • 1
  • 25
  • 26
0

jQuery $.ajax() will add the responseJSON property to the response object, and to test if the response is JSON, you can use:

if (xhr.hasOwnProperty('responseJSON')) {}
rémy
  • 1,026
  • 13
  • 18
-1

There is a tiny library that checks JavaScript types: is.js

is.json({foo: 'bar'});
=> true

// functions are returning as false
is.json(toString);
=> false

is.not.json([]);
=> true

is.all.json({}, 1);
=> false

is.any.json({}, 2);
=> true

// 'all' and 'any' interfaces can also take array parameter
is.all.json([{}, {foo: 'bar'}]);
=> true

Actually is.js is much more then this, some honorable mentions:

var obj = document.createElement('div');
is.domNode(obj);
=> true

is.error(new Error());
=> true

is.function(toString);
=> true

is.chrome();
=> true if current browser is chrome


ramazan polat
  • 7,111
  • 1
  • 48
  • 76