Der JSONP-Rückruf wird nicht ausgeführt, wenn er auf localhost ausgeführt wird
Das ist bizarr, ich habe mich gefragt, ob jemand etwas Licht darauf werfen kann, warum das passiert ist.
Grundsätzlich habe ich versucht, JSONP zu testen, damit ich einen JSON-Webdienst implementieren kann, den andere Websites verwenden können. Ich entwickle auf localhost - speziell auf Visual Studio 2008 und dem integrierten Webserver von Visual Studio 2008.
Als JSONP-Testlauf mit jQuery habe ich Folgendes implementiert:
$().ready(function() {
debugger;
try {
$.getJSON("<%= new Uri(Request.Url, "/").ToString() %>XssTest?callback=?", function(data) {
alert(data.abc);
});
} catch (err) {
alert(err);
}
});
Und auf dem Server ..
<%= Request["callback"] %>({abc : 'def'})
Am Ende wird also ein Haltepunkt auf dem Server festgelegt und der Haltepunkt wird beim ersten "Debugger" angezeigt. Anweisung im clientseitigen Skript sowie auf dem Server. Die JSONP-URL wird tatsächlich aufgerufen, nachdem die Seite geladen wurde. Das funktioniert super.
Das Problem, das ich hatte, war, dass der Rückruf nie ausgeführt werden würde. Ich habe dies sowohl in IE8 als auch in Firefox 3.5 getestet. Keiner von beiden würde den Rückruf aufrufen. Der Haken (err) wurde auch nie erreicht. Es ist überhaupt nichts passiert!
Ich war eine Woche lang dabei und habe sogar mit einer manuell verschlüsselten HTTP-Anfrage in Telnet auf dem angegebenen Port getestet, um sicherzustellen, dass der Server das Format zurückgibt ...
callbackfn({abc : 'def'})
.. und es ist.
Dann wurde mir klar, was passiert, wenn ich den Hostnamen mit einem Globalizer ('.') Von localhost in localhost ändere, d. Hhttp://localhost.:41559/ anstatthttp: // localhost: 41559 / (Ja, das Hinzufügen eines Punkts zu einem beliebigen Hostnamen ist zulässig, was für DNS giltglobal::
ist auf C # -Namensräume). Und dann hat es geklappt! Internet Explorer und Firefox 3.5 haben mir endlich eine Warnmeldung angezeigt, als ich gerade einen Punkt hinzugefügt habe.
Ich frage mich also, was hier los ist. Warum sollte die späte Erstellung von Skript-Tags mit einem Internet-Hostnamen und nicht mit einem einfachen localhost funktionieren? Oder ist das die richtige Frage?
Natürlich ist dies aus Sicherheitsgründen implementiert, aber was versuchen sie zu sichern? Und habe ich gerade eine Sicherheitslücke in diesem Sicherheitsmerkmal entdeckt, als ich dafür gesorgt habe, dass es mit einem Punkt funktioniert?
Übrigens hat meine Hosts-Datei, obwohl sie für andere Hosts geändert wurde, nichts Besonderes mit localhost zu tun. Die Standardeinstellungen 127.0.0.1 / :: 1 sind noch vorhanden und haben keine weiteren Überschreibungen.
NACHVERFOLGEN: Ich habe dies für lokale Entwicklungszwecke überwunden, indem ich Folgendes hinzugefügt habe:
127.0.0.1 local.mysite.com
.. zu meiner hosts-Datei und füge dann den folgenden Code zu meiner global.asax hinzu:
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);
}
}