0

I know I can use jQuery and other libraries to easily handle this, but I'd like to know personally the best way to handle these responses. I've spent extensive time searching for the proper way to handle them, but all I find is the same explanations for why they exist: anti-hijacking.

So, the title speaks for itself. I know a very common implementation utilizes the prepending of a while loop, which could be dealt with using .replace(/^while\(\d*\);/, ''), but this feels like a crude and hackish way to handle it and it only accounts for one possible variation.

Is there a better way to handle it?

Trying to keep it simple, an example of this would be:

var oReq = new XMLHttpRequest();
oReq.addEventListener("load", function() {
    console.log(this.responseText);
});
oReq.open("GET", "http://www.example.org/example.json");
oReq.send();

This might produce a response like:

while(1);{"menu":{"id":"file","value":"File","popup":{"menuitem":[{"value":"New","onclick":"CreateNewDoc()"},{"value":"Open","onclick":"OpenDoc()"},{"value":"Close","onclick":"CloseDoc()"}]}}}
Christopher Esbrandt
  • 1,168
  • 10
  • 21
  • 2
    How would you use jQuery? – pishpish Oct 05 '18 at 15:07
  • Well, you could match `/\{.*\}$/` and then do a JSON.parse() on whatever that returns. That will work as long as your JSON is an object, and your "anti-hijacking" string doesn't contain any braces. Exchange braces for brackets `[]` in the regex for array JSON data – mhodges Oct 05 '18 at 15:10
  • 1
    No, jQuery or other libraries *don't* handle this either. – Bergi Oct 05 '18 at 15:27
  • Only way around it is to check for each "protection" and remove it. There is not going to be a one size fits all solution. – epascarello Oct 05 '18 at 15:30
  • If I use `$.ajax({ method: 'GET', url: 'http://www.example.org/example.json', success: function(responseText) { console.log(responseText); }})` to make the same call, it parses the response without my having to do anything. In pure-JavaScript, I have to manually strip the loop before I can parse it. – Christopher Esbrandt Oct 05 '18 at 16:25
  • I stand corrected. I found out that where I was using it has a custom modification to their jQuery installation that strips it. Mystery solved. Thank you to everyone that responded! – Christopher Esbrandt Oct 05 '18 at 16:56

2 Answers2

1

this feels like a crude and hackish way to handle it and it only accounts for one possible variation.

No, it's exactly what you would do. Or even less generic, .slice(9). Servers don't prepend arbitrary or even dynamically generated loops, they use the shortest/simplest possible one to prevent JSON hijacking. So you have to deal only with that particular prefix used by the service your are requesting.

Bergi
  • 513,640
  • 108
  • 821
  • 1,164
0

Apart from replace(), another way could be using slice() out first 9 characters because while(1); has 9 characters, so you can discard it and use JSON.parse() to make it object from string.

const js_string = 'while(1);{"menu":{"id":"file","value":"File","popup":{"menuitem":[{"value":"New","onclick":"CreateNewDoc()"},{"value":"Open","onclick":"OpenDoc()"},{"value":"Close","onclick":"CloseDoc()"}]}}}';
//while(9); has 9 characters so remove it and parse it to json object
console.log(JSON.parse(js_string.slice(9)));
Always Sunny
  • 29,081
  • 6
  • 43
  • 74