Erlauben Sie Access-Control-Allow-Origin-Header mithilfe der HTML5-Abruf-API

87

Ich verwende die HTML5-Abruf-API.

var request = new Request('https://davidwalsh.name/demo/arsenal.json');

fetch(request).then(function(response) {
    // Convert to JSON
    return response.json();
}).then(function(j) {
    // Yay, `j` is a JavaScript object
    console.log(JSON.stringify(j));
}).catch(function(error) {
    console.log('Request failed', error)
});

Ich kann normales JSON verwenden, aber die Daten der obigen API-URL nicht abrufen. Es wirft Fehler:

Die Abruf-API kann https://davidwalsh.name/demo/arsenal.json nicht laden . In der angeforderten Ressource ist kein Header 'Access-Control-Allow-Origin' vorhanden. Origin ' http: // localhost ' ist daher kein Zugriff gestattet. Wenn eine undurchsichtige Antwort Ihren Anforderungen entspricht, setzen Sie den Anforderungsmodus auf "no-cors", um die Ressource mit deaktiviertem CORS abzurufen.

iNikkz
quelle
Der Server eines Drittanbieters muss dies festlegen. Auf der Clientseite können Sie nichts tun.
Epascarello
@epascarello: Wir können auf Kundenseite tun. Hinter den Kulissen läuft die XHR-Anfrage. Bitte überprüfen Sie dieshttps://davidwalsh.name/fetch
iNikkz

Antworten:

81

Wie Epascarello sagte, muss auf dem Server, auf dem sich die Ressource befindet, CORS aktiviert sein. Was Sie auf der Clientseite tun können (und wahrscheinlich an was Sie denken), ist, den Abrufmodus auf CORS zu setzen (obwohl dies meiner Meinung nach die Standardeinstellung ist):

fetch(request, {mode: 'cors'});

Dies erfordert jedoch weiterhin, dass der Server auch CORS aktiviert und Ihre Domain die Ressource anfordert.

Schauen Sie sich die CORS-Dokumentation und dieses fantastische Udacity-Video an , in dem die Richtlinien für denselben Ursprung erläutert werden .

Sie können auch No-cors Modus auf der Client - Seite verwenden, aber das wird man nur eine undurchsichtige Antwort geben (man den Körper nicht lesen können, aber die Antwort kann noch durch eine API von einem Servicemitarbeiter oder verbrauchen im Cache gespeichert werden, wie <img>) ::

fetch(request, {mode: 'no-cors'})
.then(function(response) {
  console.log(response); 
}).catch(function(error) {  
  console.log('Request failed', error)  
});
David Scales
quelle
2
Können Sie näher auf "Dies setzt jedoch voraus, dass der Server auch CORS aktiviert und Ihre Domain die Ressource anfordern muss." Ich habe erfolglos nach Anweisungen dafür gesucht.
Jayscript
2
@jayscript Der Gesamtprozess sieht folgendermaßen aus: Auf dem Client wird eine Cross-Origin-Anfrage mit Javascript gestellt. Im Fall der Abruf-API teilt der 'cors'-Modus dem Browser mit, dass es in Ordnung ist, diese Anforderung zu stellen. Wenn Sie stattdessen den Modus "No-Cors" hätten, würde der Browser die Anforderung stoppen, da dies nicht der Ursprung Ihrer App entspricht. Der Server empfängt die Anfrage und antwortet. Der Browser bestätigt, dass die Antwort die entsprechenden CORS-Header enthält, und ermöglicht in diesem Fall das Lesen der Antwort. Wenn die Header nicht vorhanden sind, gibt der Browser einen Fehler aus.
David Scales
1
@jayscript Dieser MDN-Artikel geht ins Detail. Im Wesentlichen müssen Sie auf einem Ihrer Server die folgenden Header festlegen: "Zugriffssteuerungs- Zulassungsursprung : foo.example ", "Zugriffssteuerungs-Zulassungsmethoden: POST, GET, OPTIONEN", "Zugriffssteuerungs-Zulassungs-Header: X-PINGOTHER, Content-Type ", die Ursprünge, Methoden und Header ermöglichen. In der Regel wird '*' für den Ursprungsheader verwendet. Sie können auch dieses Google-Dokument und das zugehörige Codelab überprüfen, um mehr über die Fetch-API zu erfahren: developer.google.com/web/ilt/pwa/working-with-the-fetch-api
David Scales
2
Vielen Dank! Das hilft mir zu verstehen, dass es unmöglich ist, Daten vom API-Server abzurufen, der einen anderen Ursprung hat, wenn der API-Server keine Header enthält. In dem speziellen Fall, mit dem ich es zu tun hatte, hatte ich Zugriff auf den API-Servercode und konnte selbst Header hinzufügen, was das Abrufen ermöglichte.
Jayscript
Das ist dumm, was ist das Sicherheitsproblem mit NO sendingCookies und damit CORS?
Deathangel908
14

Ich hatte meinen Front-End-Code unter http: // localhost: 3000 und meine API (Backend-Code) unter http: // localhost: 5000

Verwendete die Fetch-API, um die API aufzurufen. Anfangs warf es einen "cors" -Fehler. Fügen Sie dann den folgenden Code in meinen Backend-API-Code ein, sodass Ursprung und Header von überall aus möglich sind.

let allowCrossDomain = function(req, res, next) {
  res.header('Access-Control-Allow-Origin', "*");
  res.header('Access-Control-Allow-Headers', "*");
  next();
}
app.use(allowCrossDomain);

Sie sollten jedoch Ihre Herkunft in anderen Umgebungen wie Stage, Prod.

smsivaprakaash
quelle
20
Das ist eine schreckliche Antwort. Dies ist ein massives Sicherheitsproblem. Wenn Sie dies lesen, tun Sie dies bitte nicht.
mjones.udri
1
Dies gilt nur für das lokale Setup. Zum Beispiel, um ein kurzes Bild zu machen. Ja, es besteht ein Sicherheitsrisiko, wenn dies auch für andere bereitstellbare Umgebungen gilt. Für Einheimische
denke
12

Das hat bei mir funktioniert:

npm install -g local-cors-proxy

API-Endpunkt, den wir anfordern möchten und der CORS-Probleme aufweist:

https://www.yourdomain.com/test/list

Proxy starten:

lcp --proxyUrl https://www.yourdomain.com

 Proxy Active 

 Proxy Url: http://www.yourdomain.com:28080
 Proxy Partial: proxy
 PORT: 8010

Dann in Ihrem Client-Code neuer API-Endpunkt:

http://localhost:8010/proxy/test/list

Das Endergebnis ist eine Anfrage an https://www.yourdomain.ie/test/list ohne die CORS-Probleme!

VigKam
quelle
Bitte stellen Sie sicher, dass der Server parallel läuft. Öffnen Sie das neue cmt-Eingabeaufforderungsfenster und führen Sie den Code lcp --proxyUrl yourdomain.com
Govarthanan Venunathan aus.
8

Ich weiß, dass dies ein älterer Beitrag ist, aber ich habe festgestellt, dass ich diesen Fehler behoben habe, indem ich die IP-Adresse meines Servers anstelle des Domänennamens in meiner Abrufanforderung verwendet habe. Also zum Beispiel:

#(original) var request = new Request('https://davidwalsh.name/demo/arsenal.json');
#use IP instead
var request = new Request('https://0.0.0.0/demo/arsenal.json');

fetch(request).then(function(response) {
    // Convert to JSON
    return response.json();
}).then(function(j) {
    // Yay, `j` is a JavaScript object
    console.log(JSON.stringify(j));
}).catch(function(error) {
    console.log('Request failed', error)
});
MattG
quelle
1

Wenn Sie Nginx verwenden, versuchen Sie dies

#Control-Allow-Origin access

    # Authorization headers aren't passed in CORS preflight (OPTIONS) calls. Always return a 200 for options.
    add_header Access-Control-Allow-Credentials "true" always;
    add_header Access-Control-Allow-Origin "https://URL-WHERE-ORIGIN-FROM-HERE " always;
    add_header Access-Control-Allow-Methods "GET,OPTIONS" always;
    add_header Access-Control-Allow-Headers "x-csrf-token,authorization,content-type,accept,origin,x-requested-with,access-control-allow-origin" always;

    if ($request_method = OPTIONS ) {
        return 200;
    }

Caliari
quelle
-3

Schauen Sie unter https://expressjs.com/en/resources/middleware/cors.html nach. Sie müssen cors verwenden.

Installieren:

$ npm install cors
const cors = require('cors');
app.use(cors());

Sie müssen diesen Code in Ihren Knotenserver einfügen.

Ernersto Pastori
quelle
1
Wie können Sie wissen, ob es sich um den OP-Server handelt und in NodeJs geschrieben ist?
Marek Szkudelski
Wenn Sie einen Knotenserver erstellt haben (Entwicklungsmodus), können Sie diese Methode verwenden, um fetch in js zu verwenden.
Ernersto Pastori