Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSONP callback doesn't execute when running at localhost

Tags:

People also ask

Why is JSONP avoided?

JSONP has some other limitations, too: It can only be used for GET requests, and there's no general way to prevent cross-site request forgeries*. It's bad for private data, since any site on the web could hijack a JSONP response if the URL is known. This means it's best suited for consumption of public data feeds.

Is JSONP deprecated?

Yes, JSONP is obsolete now. There's absolutely no reason to offer a JSONP service anymore.

What is JSONP callback?

JSON with Padding, or JSONP for short, is a technique that allows developers to get around browsers' same-origin policies by exploiting the nature of the <script> element. The policy prohibits reading any responses made by websites with origins other than those currently in use.

Can JSONP execute JavaScript?

JSONP enables sharing of data bypassing same-origin policy, which disallows running JavaScript code to read media DOM elements or XMLHttpRequest data fetched from outside the page's originating site.


This is bizarre, I was wondering if anyone could shed some light on why this happened.

Basically, I've been pulling my hair out trying to test JSONP out so I can implement a JSON web service that other sites can use. I'm doing development on localhost--specifically, Visual Studio 2008 and Visual Studio 2008's built-in web server.

So as a JSONP test run w/ jQuery, I implemented the following:

$().ready(function() {
  debugger;
  try {
    $.getJSON("<%= new Uri(Request.Url, "/").ToString() %>XssTest?callback=?", function(data) {
        alert(data.abc);
    });
  } catch (err) {
    alert(err);
  }
});

And on the server ..

<%= Request["callback"] %>({abc : 'def'})

So what ends up happening is I set a breakpoint on the server and I get the breakpoint both on the first "debugger;" statment in the client-side script as well as on the server. The JSONP URL is indeed being invoked after the page loads. That's working great.

The problem I was having was that the callback would never execute. I tested this in both IE8 as well as Firefox 3.5. Neither one would invoke the callback. The catch(err) was never reached, either. Nothing happened at all!

I'd been stuck on this for a week, and even tested with a manually keyed HTTP request in Telnet on the specified port to be sure that the server is returning the format...

callbackfn({abc : 'def'})

.. and it is.

Then it dawned on me, what if I change the hostname from localhost to localhost with a globalizer ('.'), i.e http://localhost.:41559/ instead of http://localhost:41559/ (yes, adding a dot to any hostname is legal, it is to DNS what global:: is to C# namespaces). And then it worked! Internet Explorer and Firefox 3.5 finally showed me an alert message when I just added a dot.

So this makes me wonder, what is going on here? Why would late script tag generation work with an Internet hostname and not with plain localhost? Or is that the right question?

Clearly this is implemented for security reasons, but what are they trying to secure?? And, by getting it to work with a dot, did I just expose a security hole in this security feature?

By the way, my hosts file, while altered for other hosts, has nothing special going on with localhost; the default 127.0.0.1 / ::1 are still in place with no overrides below.

FOLLOW-UP: I got past this for local development purposes by adding:

127.0.0.1   local.mysite.com

.. to my hosts file, then adding the following code to my global.asax:

protected void Application_BeginRequest(object sender, EventArgs e)
{
    if (Request.Headers["Host"].Split(':')[0] == "localhost")
    {
        Response.Redirect(
            Request.Url.Scheme
            + "://"
            + "local.mysite.com"
            + ":" + Request.Url.Port.ToString()
            + Request.Url.PathAndQuery
            , true);
    }
}

Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!