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);
}
}