Ein kurzer Leitfaden für CORS
Eine Einführung in Cross-Origin Resource Sharing, die Art und Weise, wie Clients und Server kommunizieren können, auch wenn sie sich nicht in derselben Domäne befinden
Eine im Browser ausgeführte JavaScript-Anwendung kann normalerweise nur auf HTTP-Ressourcen in derselben Domäne (Herkunft) zugreifen, in der sie bereitgestellt wird.
Das Laden von Bildern oder Skripten / Stilen funktioniert immer, XHR- und Fetch-Aufrufe an einen anderen Server schlagen jedoch fehl, es sei denn, dieser Server implementiert eine Möglichkeit, diese Verbindung zuzulassen.
Dieser Weg wird als CORS, Cross-Origin Resource Sharingbezeichnet..
Auch das Laden von Webfonts mit@font-face
hat standardmäßig dieselbe Richtlinie und andere weniger
beliebte Dinge (wie WebGL-Texturen und drawImage
Ressourcen, die in die Canvas-API geladen werden).
Eine sehr wichtige Sache, die CORS benötigt, sind ES Modules, die kürzlich in modernen Browsern eingeführt wurden.
Wenn Sie auf dem Server keine CORS-Richtlinie eingerichtet haben, die Drittherstellern dienen kann, schlägt die Anforderung fehl.
Beispiel holen:
XHR-Beispiel:
Über- Origin-Ressource schlägt fehl, wenn
Wenn Sie jedoch sowohl den Server als auch den Client steuern, haben Sie alle guten Gründe, um zuzulassen, dass sie miteinander sprechen.
Wie?
Das hängt von Ihrem serverseitigen Stack ab.
Browser-Unterstützung
Ziemlich gut (im Grunde alle außer IE <10):
Beispiel mit Express
Wenn Sie Node.js und Express als Framework verwenden, verwenden Sie das CORS-Middleware-Paket.
Hier ist eine einfache Implementierung eines Express Node.js server:
const express = require('express') const app = express() app.get('/without-cors', (req, res, next) => { res.json({ msg: '???? no CORS, no party!' }) }) const server = app.listen(3000, () => { console.log('Listening on port %s', server.address().port) })
Wenn Sie mit einer Abrufanforderung aus einem anderen Ursprung auf / withoutcors klicken, wird das CORS-Problem aufgeworfen. Sie müssen lediglich das oben verlinkte cors-Paket anfordern und es als Middleware-Funktion an einen Endpoint-Request-Handler übergeben, um das Problem zu lösen.
const express = require('express') const cors = require('cors') const app = express() app.get('/with-cors', cors(), (req, res, next) => { res.json({ msg: 'WHOAH with CORS it works! ???? ????' }) }) / * der Rest der App * /
ein einfaches Glitch-Beispiel Hier arbeitet der Clientund hier ist der Code: https://glitch.com/edit/#!/flavio-cors-client.
Dies ist der Node.js Express-Server: https://glitch.com/edit/#!/flaviocopes-cors-example-express
Beachten Sie, dass die Anforderung, die fehlgeschlagen ist, weil sie die CORS-Überschriften nicht korrekt verarbeitet, weiterhin empfangen wird, wie Sie in der Anzeige "Netzwerk" sehen können, in der Sie die vom Server gesendete Nachricht finden:
Keine Antwort von CORS
Erlaube nur bestimmte Ursprünge In diesem Beispiel gibt es jedoch ein Problem: JEDE Anfrage wird vom Server als Cross-Origin akzeptiert.
Wie Sie in der Anzeige "Netzwerk" sehen können, hat die übergebene Anforderung einen Antwortheader access-control-allow-origin: *:
Sie müssen den Server so konfigurieren, dass er nur einen Ursprung zulässt und alle anderen blockiert. Wenn Sie dieselbe cors Node-Bibliothek verwenden, gehen Sie wie folgt vor:
const cors = require('cors') const corsOptions = { origin: 'https://yourdomain.com' } app.get('/products/:id', cors(corsOptions), (req, res, next) => { //... })
Sie können auch mehr servieren:
const whitelist = ['http://example1.com', 'http://example2.com'] const corsOptions = { origin: function(origin, callback) { if (whitelist.indexOf(origin) !== -1) { callback(null, true) } else { callback(new Error('Not allowed by CORS')) } } }
Preflight
Es gibt einige Anforderungen, die auf "einfache" Weise behandelt werden. Alle GET-Anforderungen gehören zu dieser Gruppe.
Auch einige POST- und HEAD-Requests tun dies ebenfalls.
POST-Anforderungen befinden sich ebenfalls in dieser Gruppe, wenn sie die Anforderung der Verwendung eines Inhalts- Art der
application/x-www-form-urlencoded
multipart/form-data
text/plain
Alle anderen Anforderungen müssen eine Phase vor der Genehmigung durchlaufen, die als Preflight bezeichnet wird. Der Browser prüft anhand einer Anforderung von OPTIONS, ob er zur Ausführung einer Aktion berechtigt ist. Eine Preflight-Anforderung enthält einige Header, die der Server zum Überprüfen von Berechtigungen verwendet (irrelevante Felder werden weggelassen):
OPTIONS /the/resource/you/request Access-Control-Request-Method: POST Access-Control-Request-Headers: origin, x-requested-with, accept Origin: https://your-origin.com
Der Server antwortet folgendermaßen (irrelevante Felder weggelassen):
HTTP/1.1 200 OK Access-Control-Allow-Origin: https://your-origin.com Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE
Wir haben nach POST gesucht, der Server sagt uns jedoch, dass wir auch andere HTTP-Anforderungstypen für diese bestimmte Ressource ausgeben können. Dem Knoten folgen. js Express-Beispiel oben, der Server muss auch die Anforderung OPTIONS verarbeiten:
var express = require('express') var cors = require('cors') var app = express() //allow OPTIONS on just one resource app.options('/the/resource/you/request', cors()) //allow OPTIONS on all resources app.options('*', cors())