Guten Abend, kann mir hier jemand auf einfache Weise erklären, wie CORS im Zusammenhang eines lokal ausgeführten Javascriptes und einer PHP API auf einem Webserver funktioniert? Ich habe auf beiden Seiten ein "*" für den Origin vergeben, bekomme aber keine Daten geliefert. Wenn das Skript auf dem Webserver liegt, funktioniert es. Danke und Gruß Kolja
Gast
#7011774
Der Browser checkt beim erhalt der Antwort, ob der Origin passt. Per default ist der erlaubte Origin der von der Url, wo der Request hin soll. Aber wenn der Server den "Access-Control-Allow-Origin" mit der Antwort mit senden, können noch weitere origins erlaubt werden. Der Origin, der mit dem erlaubtem gegengecheckt wird, ist der der Seite, die das script ausführt. Der origin ist der Teil der url aus schema://domain:port, ohne den Pfad dahinter. In manchen speziellen Situationen (z.B. wenn Authentifizierungsdaten per SSO mitgesendet werden sollen) macht der Browser aber vor dem echten request noch einem OPTION request, um zuerst zu prüfen, ob der request gemacht werden darf. Bei dem option request ist dann aber das gleiche spiel. Es gibt noch ein paar andere cors header, z.B. einer für die erlaubten Methoden. In manchen Situationen & für manche cors header funktioniert auch der wert * nicht, da muss man dann explizit sein. Das ist auch, warum gewisse APIs Access-Control-Allow-Origin auf den Wert des Origin headers vom Request setzen.
Kolja L. schrieb: > Wenn das Skript auf dem Webserver liegt Wenn es nicht am Webserver ist, ist es dann eine lokale Datei? Wie will die einen "Access-Control-Allow-Origin"-Header mitschicken, wenn sie geöffnet wird?
Danke DPA für die ausführliche Antwort, jetzt ist mir das Prinzip schon etwas deutlicher geworden. Aber zum "Laufen" habe ich es noch nicht bekommen. Ich liste mal auf ;-) Das ist die Fehlermeldung vom Browser, wenn ich meine Seite auf einem lokalen Server ausführe und die Daten vom Webserver anfordere:
1 | |
2 | |
3 | |
Mit dieser Funktion frage ich die Daten an:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
ob mit oder ohne oder anderen 'credentials' macht keinen Unterschied. Hier noch die Ausgabefunktion vom Webserver:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
Mmn sollte das ganze doch so funktionieren, oder was mache ich falsch? Danke schonmal für eure Unterstützung. Kolja
Gast
#7013822
Ich würde mal mit "curl -v" oder einem Tool wie postman oder so mal nachsehen, ob die Header auch tatsächlich gesetzt werden. In php kann man die header nur setzen, solange sie noch nicht gesendet sind. u.A. darf also noch nichts ausgegeben worden sein. Dass kann recht schnell mal passieren, z.B. wenn man einen abstand, newline, oder unicode BOM vor dem <?php stehen hat, oder sonst irgendwo im Code irgendwas ausgegeben wurde. Wenn die Warnungen ausgeschaltet sind, bekommt man davon auch gar nichts mit.
Weitere Fehlerquelle, hängt aber evtl. auch mit dem verfrühtem Output vor den header() - Aufrufen zusammen: der Browser kann die Cors-Header per "HEAD"-Request abfragen, da hast du dann keine POST-Daten, musst aber trotzdem die Header ausliefern. Und das PHP-Script wird dann evtl. beim ersten Output abgebrochen, da der HEAD-Request keinen Body erwartet.
Bin gerade nicht zuhause, aber würde bei einer PHP Ausgabe vor dem header das ganze nicht auch nicht funktionieren, wenn das JavaScript auf dem Server liegt? Das ist es ja, was mich so irritiert. Liegt beides auf dem Webserver funktioniert es, liegt das JS auf dem lokalen Server, geht es nicht.
Kolja L. schrieb: > Liegt beides auf dem Webserver > funktioniert es dann greift die Same-Origin Policy, und es sind garkeine CORS-Header nötig.
Gast
#7014230
Die Browserfehlermeldung sagt ja recht eindeutig das dev.irgendwo.de scheinbar real keinen Access-Control-Allow-Origin HTTP-Header sendet. Da würde ich im Netzwerk-Tab in den Dev-Tools des Browsers (F12-Taste) als erstes mal nachschauen wie die Header im Response und der Response selbst denn tatsächlich aussehen...
Gast
#7014282
bluppdidupp schrieb: > Da würde ich im Netzwerk-Tab in den Dev-Tools des Browsers (F12-Taste) > als erstes mal nachschauen wie die Header im Response und der Response > selbst denn tatsächlich aussehen... Ich habe da mit cross origin geschichten schlechte erfahrungen mit den browser dev tools gemacht. Die zeigen da nicht immer alles 1:1, bei den cors geschichten.
Gast
#7015040
Ich fand diese Doku dazu am hilfreichsten. Konnte es damit in mehreren Programmiersprachen auf Anhieb umsetzen: https://developer.mozilla.org/de/docs/Web/HTTP/CORS
So, nach etwas warten hat sich das Problem leider nicht von selbst behoben, aber ich habe mir die Abfrage aus dem Projekt extrahiert, um evtl. Kreuzreaktionen zu verhindern. Die api.php wird über XAMPP (Apache/PHP) ausgegeben und die JS Anfrage über den "Live-Server" des VSCode Editors gestellt. Es bleibt aber bei demselben Fehler: > Access to fetch at 'http://localhost./php/api.php?list'; from origin 'http://127.0.0.1:5500'; has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. Die Anfrage ist denkbar simpel:
1 | |
2 | |
Der Header wird wie folgt ausgegeben:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
Es ist die einzige Ausgabe der PHP-Datei (auch keine Warnungen, Fehler etc.) und wenn die Abfrage auch über XAMPP aufgerufen wird, funktioniert es. In der gewünschten Konstellation (Abfrage und Antwort auf verschiedenen (lokalen) Servern, gibt es nach der Anfrage (Kopfzeile aus den DevTools):
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
folgende Antwort:
1 | |
2 | |
3 | |
4 | |
5 | |
Hat dazu noch jemand eine Idee, oder gebe ich das Problem jetzt einfach auf? Gruß Kolja
Gast
#7024073
Kolja L. schrieb: > kann mir hier jemand auf einfache Weise erklären, wie CORS im > Zusammenhang eines lokal ausgeführten Javascriptes und einer PHP API auf > einem Webserver funktioniert? Wiso?
Gast
#7024082
Bei der Antwort ist am Anfang vermutlich noch ein "GET /php/api.php HTTP/1.1" oder so, dass man nicht sieht. Die Antwort sieht merkwürdig aus. Diese Header (scheme:, filename: Übertragen:) habe ich in einer HTTP/1.1 Response noch nie gesehen. (und wieso scheme:https, wenn im fetch http steht?!?). Den "Access-Control-Allow-Origin" Header sieht man da auch nicht. Kannst du eventuell mit Wireshark oder so nochmal nachsehen, ob da nicht was anderes gesendet wird? Oder macht der Server da vielleicht sogar irgend welchen experimentellen HTTP/2 / SPDY oder HTTP/3 / QUIC Nonsens, der da zu Problemen führt?
Alle bisherigen Angaben stammten aus dem Firefox, Chrome sagt da deutlich mehr(siehe Anhang).
Gast
#7024111
Du musst auf dem Server zwei HTTP Methoden implementieren: > OPTIONS http://localhost./php/api.php?list Muss mit einem leeren Body und folgenden Header beantwortet werden: Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: * Access-Control-Max-Age: 86400 Diese Requests hast du in deinen Logs womöglich nicht gesehen, weil der Browser die Berechtigungen cached, so dass er den OPTIONS Request beim Wiederhol-versuch normalerweise nicht erneut sendet. Danach ruft der Browser auf: > GET http://localhost./php/api.php?list Das muss mit folgendem Header beantwortet werden: Access-Control-Allow-Origin: * und was du sonst noch so als Response zurück geben wolltest. Anstelle der Sternchen kannst du natürlich restriktiver sein (Komma-separierte Listen), aber damit würde ich erstmal anfangen.
Gast
#7024124
Der Status 404 erscheint mir wichtig. Offenbar findet es die Datei unter "http://localhost./php/api.php?list" nicht. Vermutlich ist dass das Hauptproblem. Vermutlich hat der Server Probleme mit dem "localhost." Spezifischer, dem . am Schluss. "localhost." ist zwar eine gültige fqdn, es ist das selbe wie localhost, nur dass die search Domains beim DNS Lookup nicht beachtet werden. Nur senden Browser dann "Host: localhost." auch statt "Host: localhost", und die meisten Webserver oft nicht so clever zu merken, dass "Host: localhost." und localhost den selben vhost betreffen sollten. (Zumindest nicht ohne spezielle Zusatzkonfigurationen) Also nimm den . da mal weg, damit da "http ://localhost/php/api.php?list" draus wird. Oder alternativ, mach aus dem "http ://localhost" statdessen "http ://localhost/", dann wird daraus "http ://localhost/./php/api.php?list", was dann wieder passen sollte. Alternativ kann man die URL auch mit der URL Klasse zusammensetzen:
1 | |
2 | |
Gast
#7024125
Stefan ⛄ F. schrieb: >> OPTIONS http://localhost./php/api.php?list Danke für die ausführliche Antwort! Leider hatte ich das schon mal vergeblich versucht (Hinweis von stackoverflow):
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
Oder wie kann/soll ich die Anfrage (GET,POST,OPTIONS) auseinander sortieren? Die GET mache ich so:
1 | |
🐧 DPA 🐧 schrieb: > Der Status 404 erscheint mir wichtig. Offenbar findet es die Datei unter > "http://localhost./php/api.php?list"; nicht. Vermutlich ist dass das > Hauptproblem. JA :-) Ohne Punkt und mit dem o.g. Header für die OPTIONs funktioniert es! Danke, vor allem Stefan und DPA für Eure Hilfe, jetzt muss das ganze nur noch im Hauptprojekt auch funktionieren. Gruß Kolja
Gast
#7024151
Kolja L. schrieb: > Oder wie kann/soll ich die Anfrage (GET,POST,OPTIONS) auseinander > sortieren? Ist schon richtig so.
Stefan ⛄ F. schrieb: > Ist schon richtig so. Und damit funktioniert es auch im "großen" Projekt :-) Danke nochmal.
Kolja L. schrieb: > Und damit funktioniert es auch im "großen" Projekt :-) Meinst du damit die Produktivumgebung? Ich dachte da gehts ohne, weil es dort kein "Cross-Origin" sondern sowieso "Same-Origin" ist. Dann solltest du dort auch ohne Not keine CORS-Header setzen, vor allem keine so weit gefassten mit "*".
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.
