JavaScript ajax Abfragen zu Remote Webservice - Same-Origin-Policy umgehen?

Falc410

Vice Admiral
Registriert
Juni 2006
Beiträge
6.567
Hallo,

ich bin absoluter Beginner was Javascript und überhaupt Webentwicklung angeht. Ich habe jetzt eine "Webseite" entwickelt mit JQuery und KnockoutJS (eine MVC Library) die eine REST Schnittstelle abfragt (gehostet von einem Tomcat 7 Server).

Allerdings ist es angedacht die Webseite nicht auf dem gleichem Server wie das Backend zu haben, sondern diese lokal auf mobilen Endgeräten zu hosten, welche dann die Abfragen an das Backend schicken.

Beim testen musste ich feststellen, dass das nicht geht. Es kommt immer ajax Status 0 zurück - der Browser blockiert die Abfrage sobald diese nicht auf dem exakt gleichen Server geht (selbst der Port muss identisch sein). Nun habe ich schon viel gegoglet aber ich habe nur relativ komplexe Antworten gefunden die mich mehr verwirrt haben als das es nun klarer geworden ist.

Kann mich da bitte jemand in die richtige Richtung stossen? Ich bin im Moment mir nicht einmal im klaren ob nur der Browser das verbietet oder ob der Tomcat Server da auch mit beteiligt ist. Denn für den Apache Server habe ich Configeinträge für die httpd.conf bzw. Vhost Sektion gefunden um das zu erlauben.
 
Da bin ich auch schon drüber gestolpert. So wie ich das bei Wikipedia verstehe ändert sich aus Serversicht nichts. Lediglich in meiner Webseite verstecke ich die Adresse vor dem Browser..oder so ähnlich.
Ich habe hier mal ein Beispiel gefunden: https://learn.jquery.com/ajax/working-with-jsonp/

Das sieht schon relativ ähnlich aus wie der ajax call den ich mache:
Code:
    self.ajax = function(uri, method, data) {  
                var request = {  
                    url: uri,  
                    type: method,  
                    contentType: "application/json",  
                    accepts: "application/json",  
                    cache: false,  
                    dataType: 'json',  
                    data: JSON.stringify(data),  
                    beforeSend: function (xhr) {  
                        xhr.setRequestHeader("Authorization",  
                            "Basic " + btoa(self.username + ":" + self.password));  
                    },  
                    error: function(jqXHR) {  
                        console.log("ajax error " + jqXHR.status);  
                    }  
                };  
                return $.ajax(request);  
            }  
    // Und spaeter:
    self.login = function(tempID) {  
        self.ajax(self.playerURI + "/" + tempID, 'GET').done(function(data) {  
            // do stuff  
        }).fail(function(jqXHR) {  
            // handle failure);  
    }

Muss ich also nur den dataType von json in jsonp ändern und schon sollte es gehen?

Edit: Ok, mehr gelesen, mehr verstanden. Also der Server muss auch JSONP Sprechen. Im Prinzip gebe ich beim Aufruf der URL dem Sever einen Methodennamen (Callback) mit, welcher er bei mir aufruft um mir die Daten zu übermitteln. Also muss ich doch den Client und den Server anpassen. Andere Möglichkeit gibt es wohl nicht.
 
Zuletzt bearbeitet:
Zuletzt bearbeitet:
Das JSONP wäre wahrscheinlich eh kritisch gewesen, da das der Backend Entwickler einbauen hätte müssen. Auf die Config vom Tomcat kann ich zugreifen. Ich lese gerade wie ich die Filter konfiguriere aber was ich immer noch nicht kapiere ist dein erster Link.

Wie benutze ich CORS? Ich hab jetzt die Seite mehrmals gelesen aber so richtig kapiere ich das nicht. Sobald ich in den Request Header irgendetwas hineinschreibe ist es automatisch ein Preflight Request und kein normaler mehr und dann funktioniert es sofort? Ich versteh auch nicht wo das sicher sein sollte...

Und ich weiss halt auch nicht ob der Mobile Browser CORS kann oder nicht. Aber ich werde mal weiter suchen nach Jquery und CORS, vielleicht finde ich da was.

edit: Hab sogar schon was gefunden: http://www.bennadel.com/blog/2327-C...-AJAX-Requests-Between-jQuery-And-Node-js.htm
Der Typ macht doch genau den gleichen ajax request wie ich...ich seh da keinen Unterschied...
 
Zuletzt bearbeitet:
Der Browser blockt die Antwort vom Server - aufgrund der unterschiedlichen Origins, das haste schon alles richtig verstanden. Damit der Browser die Antwort trotzdem durchlässt, muss dein Server den "Access-Control-Allow-Origin" Header mit entsprechendem Wert (*) mitsenden. Steht auch in deinem verlinkten Artikel.

Wie liegen die Seiten denn auf den Mobilgeräten? Android, iOS, Windows Geräte? Wenn das letztendlich eine installierbare Web-"App" werden soll kann man da eventuell andere, elegantere Lösungen finden.
 
Für mich war bis jetzt noch nie so klar ob es am Client, am Server oder an beidem liegt. Ich versuche morgen den Tomcat mal entsprechend zu konfigurieren und dann mal schauen was passiert. Im besten Fall muss ich an meinem Code nichts ändern.

Derzeit haben wir nur Windows CE Geräte von Motorola. Motorola bietet einen HTML5 Browser an, der nennt sich RhoElements. Browser ist sogar etwas abwertend, das ist ein komplettes Framework und bietet noch x Sachen die wir gar nicht benötigen. Aber es gibt die Möglichkeit eben eine App zu bauen die man dann auf iOS, Android und Windows CE / Mobile installieren kann. Da das alles auf Web Technologie basiert sollte es dann auch überall eine fast identische User Experience geben. Die Idee war eben, die HTML, CSS und JS Daten mit in diese App zu bundlen, schon allein aus Performanzgründen - die Windows CE Geräte sind extrem langsam werden aber wohl in der Industrie immer noch recht häufig eingesetzt.

Danke für eure Hilfe auf jeden Fall!
Ergänzung ()

Also ich glaube es funktioniert. Ich kann es noch nicht 100% testen ohne die anderen Entwickler aber anscheinend hat wirklich nur der CORS Filter in der tomcat config (web.xml) gefehlt: http://tomcat.apache.org/tomcat-7.0-doc/config/filter.html#CORS_Filter

Vielen Dank für eure Hilfe.
 
Zurück
Oben