Anscheinend habe ich seine Semantik völlig missverstanden. Ich dachte an so etwas:
- Ein Client lädt den Javascript-Code MyCode.js von
http://siteA
- dem Ursprung herunter . - Der Antwortheader von MyCode.js enthält Access-Control-Allow-Origin
http://siteB
:, was meiner Meinung nach bedeutete, dass MyCode.js Ursprungsübergreifende Verweise auf die Site B erstellen durfte. - Der Client löst einige Funktionen von MyCode.js aus, die wiederum Anforderungen an stellen
http://siteB
, was trotz originalübergreifender Anforderungen in Ordnung sein sollte.
Nun, ich liege falsch. So funktioniert das überhaupt nicht. Also, ich habe gelesen , Cross-Origin Resource Sharing und versucht zu lesen Cross-Origin Resource Sharing in W3C - Empfehlung
Eines ist sicher - ich verstehe immer noch nicht, wie ich diesen Header verwenden soll.
Ich habe die volle Kontrolle über Site A und Site B. Wie aktiviere ich den von Site A heruntergeladenen Javascript-Code, um mithilfe dieses Headers auf Ressourcen auf Site B zuzugreifen?
PS
Ich möchte JSONP nicht verwenden.
javascript
cross-domain
cors
Kennzeichen
quelle
quelle
http://siteA/MyCode.js
.Antworten:
Access-Control-Allow-Origin
ist ein CORS-Header (Cross-Origin Resource Sharing) .Wenn Site A versucht, Inhalte von Site B abzurufen, kann Site B einen
Access-Control-Allow-Origin
Antwortheader senden , um dem Browser mitzuteilen, dass der Inhalt dieser Seite für bestimmte Ursprünge zugänglich ist. (Ein Ursprung ist eine Domain sowie ein Schema und eine Portnummer .) Standardmäßig sind die Seiten von Site B keinem anderen Ursprung zugänglich . Die Verwendung desAccess-Control-Allow-Origin
Headers öffnet eine Tür für den Cross-Origin-Zugriff durch bestimmte anfordernde Ursprünge.Für jede Ressource / Seite, die Site B Site A zugänglich machen möchte, sollte Site B seine Seiten mit dem Antwortheader versehen:
Moderne Browser blockieren domänenübergreifende Anfragen nicht direkt. Wenn Site A eine Seite von Site B anfordert, ruft der Browser die angeforderte Seite tatsächlich auf Netzwerkebene ab und prüft, ob in den Antwortheadern Site A als zulässige Anfordererdomäne aufgeführt ist. Wenn Standort B nicht angegeben hat , dass Standort A erlaubt ist , auf dieser Seite zuzugreifen, löst der Browser das
XMLHttpRequest
‚serror
Ereignis und verweigert die Antwortdatum an den anfordernden JavaScript - Code.Nicht einfache Anfragen
Was auf Netzwerkebene passiert, kann etwas komplexer sein als oben erläutert. Wenn es sich bei der Anforderung um eine "nicht einfache" Anforderung handelt , sendet der Browser zuerst eine datenlose "Preflight" -OPTIONS-Anforderung, um zu überprüfen, ob der Server die Anforderung akzeptiert. Eine Anfrage ist nicht einfach, wenn eine (oder beide):
Accept
Accept-Language
Content-Language
Content-Type
(dies ist nur einfach , wenn ihr Wert istapplication/x-www-form-urlencoded
,multipart/form-data
odertext/plain
)Wenn der Server auf den OPTIONS-Preflight mit geeigneten Antwortheadern (
Access-Control-Allow-Headers
für nicht einfache Header,Access-Control-Allow-Methods
für nicht einfache Verben) antwortet, die mit dem nicht einfachen Verb und / oder den nicht einfachen Headern übereinstimmen, sendet der Browser die eigentliche Anforderung.Angenommen, Site A möchte eine PUT-Anfrage senden , für die der Browser
/somePage
mit einem nicht einfachenContent-Type
Wert vonapplication/json
zuerst eine Preflight-Anfrage senden würde:Beachten Sie, dass
Access-Control-Request-Method
undAccess-Control-Request-Headers
vom Browser automatisch hinzugefügt werden. Sie müssen sie nicht hinzufügen. Dieser OPTIONS-Preflight erhält die erfolgreichen Antwortheader:Beim Senden der eigentlichen Anfrage (nach Abschluss des Preflights) ist das Verhalten identisch mit der Behandlung einer einfachen Anfrage. Mit anderen Worten, eine nicht einfache Anfrage, deren Preflight erfolgreich ist, wird genauso behandelt wie eine einfache Anfrage (dh der Server muss immer noch
Access-Control-Allow-Origin
erneut senden , um die eigentliche Antwort zu erhalten).Der Browser sendet die eigentliche Anfrage:
Und der Server sendet eine zurück
Access-Control-Allow-Origin
, genau wie bei einer einfachen Anfrage:Siehe Verständnis XMLHttpRequest über CORS für ein wenig mehr Informationen über nicht-einfache Anfragen.
quelle
Access-Control-Allow-Origin
Header zu überprüfen , liefert jedoch möglicherweise keine Antwort auf den JS-Code an Standort A, wenn der Header den Standort A nicht zulässt. (PS Danke :))Access-Control-Allow-Origin
Akzeptiert bei Verwendung einer Authentifizierung die*
in einigen Browsern (FF und Chrome AFAIK) nicht. In diesem Fall müssen Sie also den Wert aus derOrigin
Kopfzeile angeben . Hoffe, dass dies jemandem helfen wird.Cross-Origin Resource Sharing -
CORS
(AKA-domänenübergreifende AJAX-Anforderung) ist ein Problem, auf das die meisten Webentwickler laut Same-Origin-Policy stoßen könnten. Browser beschränken Client-JavaScript in einer Sicherheits-Sandbox. Normalerweise kann JS nicht direkt mit einem Remote-Server kommunizieren aus einer anderen Domäne. In der Vergangenheit haben Entwickler viele knifflige Methoden entwickelt, um domänenübergreifende Ressourcenanforderungen zu erfüllen. Am häufigsten werden folgende Methoden verwendet:Diese kniffligen Methoden haben mehr oder weniger einige Probleme, zum Beispiel könnte JSONP zu Sicherheitslücken führen, wenn Entwickler es einfach "bewerten", und # 3 oben, obwohl es funktioniert, sollten beide Domänen strenge Verträge untereinander aufbauen, weder flexibel noch elegant MEINER BESCHEIDENEN MEINUNG NACH:)
W3C hatte Cross-Origin Resource Sharing (CORS) als Standardlösung eingeführt, um eine sichere, flexible und empfohlene Standardmethode zur Lösung dieses Problems bereitzustellen.
Der Mechanismus
Auf hoher Ebene können wir einfach davon ausgehen, dass CORS ein Vertrag zwischen dem AJAX-Clientaufruf von Domain A und einer auf Domain B gehosteten Seite ist. Eine typische Cross-Origin-Anfrage / Antwort wäre:
DomainA AJAX-Anforderungsheader
DomainB-Antwortheader
Die blauen Teile, die ich oben markiert habe, waren die Kernfakten. "Origin" -Anforderungsheader "gibt an, woher die Cross-Origin-Anforderung oder Preflight-Anforderung stammt". Der Antwortheader "Access-Control-Allow-Origin" gibt an, dass diese Seite Remote-Anforderungen zulässt DomainA (wenn der Wert * ist, können Sie Remote-Anforderungen von jeder Domain zulassen).
Wie oben erwähnt, hat W3 dem Browser empfohlen, eine " Preflight-Anforderung " zu implementieren, bevor die eigentliche Cross-Origin-HTTP-Anforderung gesendet wird. Kurz gesagt handelt es sich um eine HTTP-
OPTIONS
Anforderung:Wenn foo.aspx das HTTP-Verb OPTIONS unterstützt, wird möglicherweise die folgende Antwort zurückgegeben:
Nur wenn die Antwort "Access-Control-Allow-Origin" enthält UND ihr Wert "*" ist oder die Domäne enthält, die die CORS-Anforderung gesendet hat, sendet der Browser bei Erfüllung dieser obligatorischen Bedingung die tatsächliche domänenübergreifende Anforderung und speichert das Ergebnis zwischen in " Preflight-Result-Cache ".
Ich habe vor drei Jahren über CORS gebloggt: AJAX Cross-Origin HTTP-Anfrage
quelle
Die Frage ist etwas zu alt, um sie zu beantworten, aber ich poste sie für zukünftige Verweise auf diese Frage.
Laut diesem Artikel des Mozilla Developer Network
Eine HTML-Seite, die von bereitgestellt wird,
http://domain-a.com
stellt eine<img>
src-Anfrage fürhttp://domain-b.com/image.jpg
.Viele Seiten im Web laden heute Ressourcen wie CSS-Stylesheets , Bilder und Skripte aus separaten Domänen (daher sollte es cool sein).
Richtlinie mit gleichem Ursprung
Aus Sicherheitsgründen beschränken Browser Ursprungsübergreifende HTTP- Anforderungen, die aus Skripten heraus initiiert werden .
Zum Beispiel,
XMLHttpRequest
undFetch
folgen Sie der same-origin policy .Eine Webanwendung, die HTTP-Anforderungen verwendet
XMLHttpRequest
oderFetch
nur an ihre eigene Domäne senden kann .Cross-Origin Resource Sharing (CORS)
Um Webanwendungen zu verbessern, baten Entwickler Browseranbieter, domänenübergreifende Anforderungen zuzulassen.
Der CORS- Mechanismus (Cross-Origin Resource Sharing) bietet Webservern domänenübergreifende Zugriffskontrollen , die sichere domänenübergreifende Datenübertragungen ermöglichen.
Moderne Browser verwenden CORS in einem API-Container - wie
XMLHttpRequest
oderFetch
-, um das Risiko von Ursprungs-HTTP-Anforderungen zu verringern.Wie CORS funktioniert (
Access-Control-Allow-Origin
Header)Wikipedia :
Beispiel
Der Browser sendet die
OPTIONS
Anfrage mit einemOrigin HTTP
Header.Der Wert dieses Headers ist die Domäne, die die übergeordnete Seite bedient hat. Wenn eine Seite
http://www.example.com
versucht, auf die Daten eines Benutzers zuzugreifenservice.example.com
, wird der folgende Anforderungsheader an gesendetservice.example.com
:Herkunft: http://www.example.com
Der Server von
service.example.com
kann antworten mit:Ein
Access-Control-Allow-Origin
(ACAO) -Header in seiner Antwort, der angibt, welche Ursprungsorte zulässig sind.Zum Beispiel:
Access-Control-Allow-Origin: http://www.example.com
Eine Fehlerseite, wenn der Server die Cross-Origin-Anforderung nicht zulässt
Ein
Access-Control-Allow-Origin
(ACAO) -Header mit einem Platzhalter, der alle Domänen zulässt:Access-Control-Allow-Origin: *
quelle
Access-Control-Allow-Origin:null
Access-Control-Allow-Origin
? Ich meine die Verneinung vonAccess-Control-Allow-Origin: *
Immer wenn ich über CORS nachdenke, ist meine Intuition darüber, auf welcher Site die Header gehostet werden, falsch, genau wie Sie es in Ihrer Frage beschrieben haben. Für mich ist es hilfreich, über den Zweck derselben Ursprungspolitik nachzudenken.
Der Zweck derselben Ursprungsrichtlinie besteht darin, Sie vor böswilligem JavaScript auf siteA.com zu schützen, das auf private Informationen zugreift, die Sie nur für siteB.com freigeben möchten. Ohne dieselbe Ursprungsrichtlinie könnte JavaScript, das von den Autoren von siteA.com geschrieben wurde, Ihren Browser dazu bringen, Anfragen an siteB.com zu richten, indem er Ihre Authentifizierungscookies für siteB.com verwendet. Auf diese Weise könnte siteA.com die geheimen Informationen stehlen, die Sie mit siteB.com teilen.
Manchmal müssen Sie domänenübergreifend arbeiten. Hier kommt CORS ins Spiel. CORS lockert die gleiche Ursprungsrichtlinie für domainB.com und verwendet den
Access-Control-Allow-Origin
Header, um andere Domänen (domainA.com) aufzulisten, denen JavaScript zur Ausführung mit domainA als vertrauenswürdig eingestuft wird. com.Berücksichtigen Sie dies, um zu verstehen, welche Domäne die CORS-Header bedienen soll. Sie besuchen malicious.com, das JavaScript enthält, das versucht, eine domänenübergreifende Anfrage an mybank.com zu stellen. Es sollte an mybank.com und nicht an böswilliger Partei liegen, zu entscheiden, ob CORS-Header festgelegt werden, die dieselbe Ursprungsrichtlinie lockern, sodass das JavaScript von malicious.com mit ihm interagieren kann. Wenn malicous.com eigene CORS-Header festlegen könnte, die einen eigenen JavaScript-Zugriff auf mybank.com ermöglichen, würde dies dieselbe Ursprungsrichtlinie vollständig ungültig machen.
Ich denke, der Grund für meine schlechte Intuition ist der Standpunkt, den ich bei der Entwicklung einer Website habe. Es ist meine Website mit all meinem JavaScript, daher macht es nichts Bösartiges und es sollte an mir liegen , anzugeben, mit welchen anderen Websites mein JavaScript interagieren kann. Wann sollte ich tatsächlich überlegen, welche anderen Websites JavaScript versucht, mit meiner Website zu interagieren, und sollte ich CORS verwenden, um sie zuzulassen?
quelle
1. Ein Client lädt den Javascript-Code MyCode.js von http: // siteA - dem Ursprung herunter .
Der Code, der das Herunterladen durchführt - Ihr HTML-Skript-Tag oder xhr aus Javascript oder was auch immer - stammt beispielsweise von http: // siteZ . Und wenn der Browser MyCode.js anfordert, sendet er einen Origin: -Header mit der Aufschrift "Origin: http: // siteZ ", da er sieht, dass Sie an siteA und siteZ! = SiteA anfordern. (Sie können dies nicht stoppen oder stören.)
2. Der Antwortheader von MyCode.js enthält Access-Control-Allow-Origin: http: // siteB , was meiner Meinung nach bedeutete, dass MyCode.js Ursprungsübergreifende Verweise auf die Site B erstellen durfte.
Nein. Dies bedeutet, dass nur siteB diese Anforderung ausführen darf. Ihre Anfrage nach MyCode.js von siteZ erhält stattdessen einen Fehler, und der Browser gibt Ihnen normalerweise nichts. Wenn Sie Ihren Server jedoch dazu bringen, ACAO: siteZ zurückzugeben, erhalten Sie MyCode.js. Oder wenn es '*' sendet, funktioniert das, das lässt alle herein. Oder wenn der Server die Zeichenfolge immer aus dem Origin: -Header sendet ... aber ... aus Sicherheitsgründen, wenn Sie Angst vor Hackern haben Ihr Server sollte nur Ursprünge auf einer Shortlist zulassen, die diese Anforderungen stellen dürfen.
Dann kommt MyCode.js von siteA. Wenn Anfragen an siteB gestellt werden, handelt es sich alle um Cross-Origin-Anfragen. Der Browser sendet Origin: siteA, und siteB muss die SiteA übernehmen, erkennen, dass sie auf der kurzen Liste der zulässigen Anforderer steht, und ACAO: siteA zurücksenden. Nur dann lässt der Browser Ihr Skript das Ergebnis dieser Anforderungen abrufen.
quelle
Verwenden von React und AxiosVerbinden Sie den Proxy-Link mit der URL und fügen Sie den Header wie unten gezeigt hinzu
https://cors-anywhere.herokuapp.com/
+Your API URL
Nur durch Hinzufügen des Proxy-Links funktioniert es, aber es kann auch wieder Fehler für No Access auslösen. Daher ist es besser, den Header wie unten gezeigt hinzuzufügen.
WARNUNG: Nicht in der Produktion verwenden
quelle
Wenn Sie nur eine domänenübergreifende Anwendung testen möchten, in der der Browser Ihre Anfrage blockiert, können Sie Ihren Browser einfach im unsicheren Modus öffnen und Ihre Anwendung testen, ohne Ihren Code zu ändern und ohne Ihren Code unsicher zu machen. Unter MAC OS können Sie dies über die Terminalleitung tun:
quelle
Wenn Sie PHP verwenden, versuchen Sie, den folgenden Code am Anfang der PHP-Datei hinzuzufügen:
Wenn Sie localhost verwenden, versuchen Sie Folgendes:
Wenn Sie externe Domänen wie Server verwenden, versuchen Sie Folgendes:
quelle
Ich arbeite mit Express 4 und Node 7.4 und Angular. Ich hatte das gleiche Problem. Ich helfe dabei:
a) Serverseite: In der Datei app.js gebe ich allen Antworten Header wie:
Dies muss vor allen Router haben .
Ich habe viele dieser Header hinzugefügt gesehen:
aber ich brauche das nicht,
b) clientseitig: in send ajax musst du hinzufügen: "withCredentials: true", wie:
Viel Glück.
quelle
res.header('Access-Control-Allow-Origin', req.headers.origin);
ist das gleiche wieres.header('Access-Control-Allow-Origin', '*');
Legen Sie für die Ursprungsfreigabe die Überschrift fest:
'Access-Control-Allow-Origin':'*';
Php:
header('Access-Control-Allow-Origin':'*');
Knoten:
app.use('Access-Control-Allow-Origin':'*');
Auf diese Weise können Inhalte für verschiedene Domänen freigegeben werden.
quelle
In Python habe ich die
Flask-CORS
Bibliothek mit großem Erfolg verwendet. Es macht den Umgang mit CORS super einfach und schmerzlos. Ich habe Code aus der folgenden Dokumentation der Bibliothek hinzugefügt.Installation:
Einfaches Beispiel, das CORS für alle Domänen auf allen Routen ermöglicht:
Weitere Beispiele finden Sie in der Dokumentation. Ich habe das obige einfache Beispiel verwendet, um das CORS-Problem in einer von mir erstellten Ionenanwendung zu umgehen, die auf einen separaten Kolbenserver zugreifen muss.
quelle
Aus meiner eigenen Erfahrung ist es schwierig, eine einfache Erklärung zu finden, warum CORS überhaupt ein Problem darstellt.
Sobald Sie verstehen, warum es dort ist, werden die Überschriften und die Diskussion viel klarer. Ich werde es in ein paar Zeilen versuchen.
Es geht nur um Cookies. Cookies werden von ihrer Domain auf einem Client gespeichert.
Wichtiger Punkt: Wenn ein Client eine Anfrage an den Server stellt, sendet er die Cookies, die unter der Domäne gespeichert sind, in der sich der Client befindet.
Wenn ein anderer Client eine Cross-Origin- Anfrage an einen Server stellt, werden diese Cookies wie zuvor gesendet. Ruh roh.
Da die Cookies wie erwartet validiert werden, autorisiert der Server die Antwort.
Huch.
Nun werden einige Fragen und Antworten offensichtlich:
quelle
Fügen Sie einfach den folgenden Code in Ihre Datei web.config ein.
Beachten Sie, dass Sie den folgenden Code unter
<system.webServer>
tag einfügen müssenquelle
Weitere Informationen finden Sie hier ....
quelle
Nginx und Appache
Als Ergänzung zur Antwort von apsillers möchte ich ein Wiki-Diagramm hinzufügen, das zeigt , ob die Anfrage einfach ist oder nicht (und die OPTIONS-Anfrage vor dem Flug gesendet wird oder nicht).
Für einfache Anfragen (z. B. Hotlinking-Bilder ) müssen Sie Ihre Serverkonfigurationsdateien nicht ändern, aber Sie können Header in Anwendungen (auf Servern gehostet, z. B. in PHP) hinzufügen, wie Melvin Guerrero in seiner Antwort erwähnt - aber denken Sie daran Sie : Wenn Sie vollständig hinzufügen cors-Header in Ihrem Server (config) und gleichzeitig erlauben Sie einfache cors in der Anwendung (z. B. PHP), dies funktioniert überhaupt nicht.
Und hier sind Konfigurationen für zwei beliebte Server
einschalten CORS auf Nginx (
nginx.conf
Datei)Code-Snippet anzeigen
einschalten CORS auf Appache (
.htaccess
Datei)Code-Snippet anzeigen
quelle