HowTo: Cross Domain Ajax mit JSONP und ASP.NET

image Eigentlich kann man Ajax Requests nur an Adressen senden die unter der gleichen Domain erreichbar sind wie die Seite auf der das Script ausgeführt wird. Der Grund dafür ist die Same Origin Policy in Javascript, diese besagt das der Port, das Protokoll und die Domain gleich sein müssen um Anfragen starten zu dürfen. Das ist zwar sicher, aber leider nicht immer praktisch.


Aber da gibt”™s doch bestimmt einen Trick?

Ja. Es gibt sogar eine ganze Menge verschiedener Möglichkeiten das Problem zu umgehen. Wenn man nach “Cross Domain Ajax” such bekommt man einen bunten Strauß an Lösungen, ich hab bestimmt einen halben Tag gebraucht um mir die verschieden Lösungen anzuschauen. Man könnte einen zum Beispiel einen Proxy einsetzen oder Flash/Silverlight nutzen usw… Für mich war die beste Lösung JSONP zu nutzen.

 

Was ist JSONP?

JSONP steht für “JSON with padding”. Die Idee ist so simpel wie Clever, man macht sich eine Sicherheitslücke in der Implementation der Same Origin Policy der Browser zu nutze. Man kann zwar keine Requests zu anderen Domains starten aber man kann dynamisch Javascript Dateien von anderen Domains einbinden. Und in diese packt man einfach seine Daten. Das Ganze hat den Nachteil das man Daten nur per GET übergeben kann und kein POST möglich ist. Wer mehr Daten übertragen möchte kann allerdings auf andere Tricks zurückgreifen oder muss sich etwas einschränken.
jQuery macht die Implementation an dieser Stelle wieder sehr einfach und gibt uns die entsprechenden Methoden an die Hand.

Und so sieht”™s aus

 
Auf dem Client:
      $.ajax({
                dataType: 'jsonp',
                jsonp: 'jsonp_callback',
                url: 'http://localhost:56761/TestService.ashx',
                success: function (j) {
                    alert(j.response);
                },
            });     

Der Unterschied zum “normalen” jQuery Request ist eigentlich nur die Zeile “jsonp: ‘jsonp_callback’” diese gibt den GET Parameternamen an in dem jQuery den Namen der Calback Funktion an den Server übermittelt.

Bei jQuery funktioniert das ganze so:

  1. Es wird ein <script> Tag erzeugt das auf die angegebene Adresse verweist, dabei wird als Parameter wird eine Zufallszahl übergeben(das ist dann der Name der Callbackfunktion).
  2. Der Server baut als Antwort eine Javascript-Datei zusammen die eine Funktion mit dem Namen der Zufallszahl aufruft und die Daten im JSON Format übergibt.
  3. Der Browser bindet das Script ein und führt das ganze aus. jQuery übergibt uns jetzt die Daten an das “success” Event.
Und auf dem Server:
string response = context.Request.Params["jsonp_callback"];
       response += "({\"response\":\"" + context.Session["RequestCounter"]  + " requests startet\"});";
context.Response.Write(response);

image

Für dieses Beispiel habe ich einen Generic Handler (.ashx) benutzt. Man könnte sicherlich auch einen WCF benutzen.

Die Beispielanwendung besteht aus zwei Projekten, einen Client das “CrossDomainAjax” Projekt und einen Service dem “SourceDomain” Projekt. Um die Demo zu starten müsst ihr mit:

Rechtsklick auf den Projektnamen -> Debug -> Start New Instance

Beide Projekte starten. Danach solltest du dann ein alert mit einer 1 im Browser sehen. Mit diesen Beispiel habe ich noch ausprobiert ob ich auf dem Server dann auch Zugriff auf die Sessesion habe. Und es geht. Bei jeden neu laden der Seite erhöht sich dann der Wert um eins. Gut, das ist jetzt kein spannendes Beispiel aber ich hoffe ihr verzeiht mit das :)

Den Demo Code gibt”™s hier. Viel Spaß.


Kick It auf dotnet-kicks.de
Wenn dir der Blogpost gefallen hat, dann hinterlasse doch einen Kommentar. Wenn du auf dem Laufenden bleiben willst, abonniere unseren RSS Feed oder folge uns auf Twitter.

About the author

Written by Oliver Guhr

Currently there is no additional info about this author.

5 Responses

  1. Sehr interessanter Ansatz, muss ich bei Gelegenheit direkt mal ausprobieren. Aber holt man sich damit nich auch irgendwo ne riesen Sicherheitslücke ins Haus?

    Reply
  2. Grundsätzlich, nein, also nicht mehr als bei jeden anderen Web Service. Es könnte sein das man deinem Javascript Code per XSS eine andere Web Service Adresse unterschiebt, die Frage ist ob das dem Angreifer was bringt.

    Reply
  3. Hallo,
    danke für die Tipps. Ich war schon am Verzweifeln, weil ich von dieser Sicherheitsmaßnahme nichts wußte. Leider liefert Firefox keinen Fehler, sondern nur Status=0.
    Erst Opera zeigte den Fehler in der Fehlerkonsole.
    Ich nutze aber lieber einen Proxy. Das erscheint mir sauberer und vor allem zukunftssicherer. Denn wer weiß, wie lange dieses Workaround noch funktionieren wird:

    Hier mein Beispiel anhand von google maps
    Diese Datei liefert schön valided XML an den AJAX-Ausruf.

    Datei: proxy.php

    header(‘Content-type: text/xml; charset=”utf-8″‘,true);
    readfile(‘http://maps.google.com/maps/api/geocode/xml?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=false‘);

    Reply
  4. Hallo Jürgen,

    natürlich ist der Proxyansatz deutlich eleganter – allerdings gibt es genügend Fälle wo man keine Chance hat einen Proxy einzusetzen oder aber man möchte es den Benutzer möglichst einfach machen wie z.B. bei der Einbindung eines Widget. Als Beispiel mal das Widget von Twitter .. ich glaube nicht das viele Leute es einbinden könnten, wenn man noch serverseitig einen “Proxy” einbinden müsste. Selbst wenn es sich hier um einen simplen Kopiervorgang geht…

    Wie gesagt, bei einer eigenen Lösung die man nicht auf andere Websiten verteilen möchte ganz klar Proxy.. ansonsten halt wie hier beschrieben.

    Viele Grüße
    Daniel

    Reply

Comment on this post

Letzte Posts

  • image.png
    Chocolatey–apt-get für Windows

    Durch Zufall bin ich auf das Tool “Chocolatey” gestoßen. Wer die Website sich anschaut, wird evtl. eine Verwandschaft mit NuGet ausmachen. Was macht Chocolatey? Chocolatey ist ein “Maschine Package Manager”, das bedeutet, dass man für seine Maschine einfach Tools runterladen und Updaten kann – direkt über die Konsole. Was ist der Unterschied zu NuGet? NuGet ...

  • image.png
    SASS, LESS & Coffeescript in Visual Studio mit der Web Workbench

    CSS und Javascript sind die “kleinste” Schnittmenge von allen Browsern für die Erstellung von Web-Applikationen. Leider geht dabei etwas komfort verloren, daher lieben alle Webentwickler jQuery! SASS und LESS sind zwei Varianten, wie man “schöner” CSS schreiben kann und Coffeescript versucht Javascript Entwicklung zu vereinfachen. Aber immer der Reihe nach… Was ist SASS? SASS steht ...

  • image.png
    Code-Inside Sample nun auf GitHub: Google Code zu GitHub Migration

    Seit einiger Zeit habe ich Beispielcode auf Google Code bereitgestellt. Einfach nur noch weg von Google Code O-Ton damals war: Ich hatte mich für Google Code entschieden, weil ich hoffe dass früher oder später die Google Code Suche nutzbar ist und es dadurch wenigstens ein kleiner Mehrwert entsteht. Allerdings wirft es momentan noch ein Fehler. ...

  • image.png
    Windows-8-Hackathon @Night in Leipzig

    Hacken (=Entwickeln, nichts böswilliges!), Grillen und mitten in der Nacht fachsimpeln? Dann ist vielleicht der Windows-8-Hackathon was für dich. Der Hackathon wird vom 15. Juni (ab 19:00) bis zum 16. Juni (bis in die frühen Morgenstunden) in Leipzig stattfinden.  Mit dabei sind auch Darius Parys und Tom Wendel von der Microsoft Deutschland. Thematisch (wie der ...

  • image.png
    Einstieg in Redis on Windows & Redis mit .NET benutzen

    Redis gehört zu den NoSQL Datenbanken und ist dort in der Familie der Key-Value Stores zu finden. Redis wird oft mit “Blazing Fast” betitelt und laut dem Stackoverflow Thread soll es im Vergleich zu MongoDB zweimal (beim Schreiben) und sogar dreimal (beim Lesen) so schnell sein wie MongoDB – auch wenn der Vergleich etwas “hinkt” ...

Auf Amazon einkaufen & unterstützen

Facebook