Handling a JSONP nightmare
I will start introducing my problem: I work for a recommendation systems company so our clients are e-commerce stores. Sometimes we need to do customize our solutions to them. Here begin my issue. One of these custom features was to use what we call “price API”. The name is self-explainable but it is an API where I can fetch a product’s price. It is very useful and can even have custom stuffs related to client business. One client decided to do such API using JSONP, so far so good, but the callback param couldn’t be modified (don’t ask me why).
What is JSONP?
A question everyone that works with web development have had. It stands for JSON with Padding. W3C (https://www.w3schools.com/js/js_json_jsonp.asp) says it is “a method for sending JSON data without worrying about cross-domain issues.”. I prefer to call it web’s jerry-rig. It indeed helps a lot but there are other ways (nowadays) to solve CORS issues than using JSONP. But it might help sometimes (Yes, it is useful, you should know how it works as you may face it in the future).
As you might know, JSONP callback should be customizable so you avoid conflicts when handling multiple JSONP calls, for example. If you are familiar with jQuery, they do all the dirty part in background, so you might see some callbacks like jQuery_123456789 to avoid conflicts.
As I introduced the problem earlier, I wasn’t allowed to customize the callback param. It didn’t matter what I would send as callback, the server would always respond with the same default callback.
There would be no problem IF I was the only one fetching these resources. But there were other third-party scripts doing the same and even I would have to do multiples calls with different handle functions sometimes, depending on the page.
So how to avoid conflicts in this case?
Well, if we look closer to the problem the issue is the following: our context window has just one callback to handle all the requests. As we can’t have multiple callbacks on the context window (As it would be if callback param could be customized) how about having multiple context windows and just one callback on each of them? And these callbacks could even refer to a function of my choice on the main context. So no conflicts at all. I would still be able to create different callbacks (functions) on the main context for each JSONP call without changing the callback param.
If you are quite familiar with web development you might have already understood what I meant. When I say “main context window” I’m referring to window.top (Main window object from your webpage). When I say “multiple context windows” I’m referring to iframes’ window objects (Accessed through iframe.contentWindow).
So what I did was: for each JSONP call I had to make, I created a new iframe, created my JSONP callback inside its context window and inserted the script tag (JSONP call) inside this iframe. This way the JSONP would live inside this limited context and as I’ve created the iframe I wouldn’t face any issues accessing its context window (iframe.contentWindow).
The picture below shows how it would be if the JSONP callback was called “a”:
This was the solution I came up with(And by the way worked without any further issues) to solve my problem. You might have been asking why I haven’t asked the client to change their implementation… Yes, I did and they didn’t listen to me. Hopefully you won’t need to do it while developing but if you do, I hope it has helped you somehow.