509 Stimmen

CORS: Kann kein Platzhalter in Access-Control-Allow-Origin verwenden, wenn das credentials-Flag auf true gesetzt ist

Ich habe ein Setup, das Folgendes umfasst

Frontend-Server (Node.js, Domain: localhost:3000) <---> Backend (Django, Ajax, Domain: localhost:8000)

Browser <-- webapp <-- Node.js (Die App bereitstellen)

Browser (webapp) --> Ajax --> Django (Ajax-POST-Anfragen bereitstellen)

Mein Problem hier liegt jetzt beim CORS-Setup, das die Web-App verwendet, um Ajax-Aufrufe an den Backend-Server zu tätigen. In Chrome erhalte ich immer

Kann kein Platzhalter in Access-Control-Allow-Origin verwenden, wenn das Flag für Berechtigungen true ist.

Funktioniert auch nicht in Firefox.

Mein Node.js-Setup ist:

var allowCrossDomain = function(req, res, next) {
    res.header('Access-Control-Allow-Origin', 'http://localhost:8000/');
    res.header('Access-Control-Allow-Credentials', true);
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
};

Und in Django verwende ich dieses Middleware zusammen mit diesem

Die Web-App sendet Anfragen wie folgt:

$.ajax({
    type: "POST",
    url: 'http://localhost:8000/blah',
    data: {},
    xhrFields: {
        withCredentials: true
    },
    crossDomain: true,
    dataType: 'json',
    success: successHandler
});

Also sehen die Anfrageheader, die die Web-App sendet, wie folgt aus:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: "Origin, X-Requested-With, Content-Type, Accept"
Access-Control-Allow-Methods: 'GET,PUT,POST,DELETE'
Content-Type: application/json 
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Cookie: csrftoken=***; sessionid="***"

Und hier ist der Antwort-Header:

Access-Control-Allow-Headers: Content-Type,*
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST,GET,OPTIONS,PUT,DELETE
Content-Type: application/json

Wo mache ich einen Fehler?!

Bearbeiten 1: Ich habe chrome --disable-web-security benutzt, aber möchte jetzt, dass die Dinge tatsächlich funktionieren.

Bearbeiten 2: Antwort:

Also die Lösung für mich ist die django-cors-headers Konfiguration:

CORS_ORIGIN_ALLOW_ALL = False
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = (
    'http://localhost:3000' # Hier lag tatsächlich das Problem und es muss http://localhost:3000 heißen, nicht http://localhost:3000/
)

15voto

Squirrl Punkte 4490

Wenn Sie alle Ursprünge zulassen und Anmeldeinformationen beibehalten möchten, hat das für mich funktioniert:

app.use(cors({
  origin: function(origin, callback){
    return callback(null, true);
  },
  optionsSuccessStatus: 200,
  credentials: true
}));

9voto

Renaud Punkte 4399

Dies funktioniert für mich in der Entwicklung, aber ich kann das nicht für die Produktion empfehlen, es ist nur ein anderer Weg, um die Aufgabe zu erledigen, der noch nicht erwähnt wurde, aber wahrscheinlich nicht der beste ist. Wie auch immer, hier ist es:

Sie können den Ursprung aus der Anfrage erhalten und ihn dann im Antwortheader verwenden. So sieht es in express aus:

app.use(function(req, res, next) {
  res.header('Access-Control-Allow-Origin', req.header('origin') );
  next();
});

Ich weiß nicht, wie das in Ihrer Python-Setup aussieht, aber das sollte leicht zu übersetzen sein.

4voto

eriel marimon Punkte 973

(Bearbeiten) Das zuvor empfohlene Add-On ist nicht mehr verfügbar, Sie können dieses andere Add-On ausprobieren


Zu Entwicklungszwecken in Chrome, die Installation von diesem Add-On wird diesen spezifischen Fehler beseitigen:

Der Zugriff auf XMLHttpRequest unter 'http://192.168.1.42:8080/sockjs-node/info?t=1546163388687' von der Herkunft 'http://localhost:8080' wurde durch die CORS-Richtlinie blockiert: Der Wert des 'Access-Control-Allow-Origin'-Headers in der Antwort darf nicht das Platzhalterzeichen '*' sein, wenn der Anforderungscredentials-Modus 'include' ist. Der Credentials-Modus von Anforderungen, die vom XMLHttpRequest initiiert wurden, wird durch das withCredentials-Attribut gesteuert.

Nach der Installation stellen Sie sicher, dass Sie Ihr URL-Muster zu den Abgefangenen URLs hinzufügen, indem Sie auf das Symbol des Add-Ons (CORS, grün oder rot) klicken und das entsprechende Textfeld ausfüllen. Ein Beispiel-URL-Muster, das hier hinzugefügt werden soll und mit http://localhost:8080 funktioniert, wäre: *://*

3voto

Auch wenn wir viele Lösungen bezüglich des CORS-Ursprungs haben, denke ich, dass ich einen fehlenden Teil hinzufügen kann. Im Allgemeinen dient die Verwendung von CORS-Middleware in node.js maximalen Zwecken wie verschiedenen HTTP-Methoden (get, post, put, delete).

Aber es gibt Anwendungsfälle wie das Senden von Cookie-Antworten, bei denen wir credentials als true innerhalb der CORS-Middleware aktivieren müssen, oder wir können kein Cookie setzen. Es gibt auch Anwendungsfälle, um Zugriff auf alle Ursprünge zu gewähren. In diesem Fall sollten wir Folgendes verwenden:

{credentials: true, origin: true}

Für einen spezifischen Ursprung müssen wir den Ursprungsnamen angeben:

{credentials: true, origin: "http://localhost:3000"}

Für mehrere Ursprünge:

{credentials: true, origin: ["http://localhost:3000", "http://localhost:3001" ]}

In einigen Fällen müssen möglicherweise mehrere Ursprünge zugelassen werden. Ein Anwendungsfall besteht darin, nur Entwicklern Zugriff zu gewähren. Um dieses dynamische Whitelisting zu haben, können wir diese Art von Funktion verwenden:

const whitelist = ['http://developer1.com', 'http://developer2.com']
const corsOptions = {
origin: (origin, callback) => {
    if (whitelist.indexOf(origin) !== -1) {
      callback(null, true)
    } else {
      callback(new Error())
    }
  }
}

1voto

Shreyash Tech Punkte 11

CORS FEHLER mit NETLIFY und HEROKU

Eigentlich, wenn keines der oben genannten Lösungen für Sie funktioniert hat, dann möchten Sie vielleicht dies ausprobieren. In meinem Fall lief das Backend auf Heroku und das Frontend wurde auf Netlify gehostet. in der .env-Datei des Frontend war die server_url wie folgt geschrieben

REACT_APP_server_url = "https://ci-cd-backend.herokuapp.com"

und im Backend wurden alle meine API-Aufrufe wie folgt geschrieben,

app.get('/login', (req, res, err) => {});

Also, die einzige Änderung, die Sie vornehmen müssen, ist das Hinzufügen von /api am Ende der Routen,

also wird die Basis-URL des Frontends wie folgt aussehen,

REACT_APP_server_url = "https://ci-cd-backend.herokuapp.com/api"

und die Backend-APIs sollten wie folgt geschrieben werden,

app.get('/api/login', (req, res, err) => {})

Dies hat in meinem Fall funktioniert, und ich glaube, dass dieses Problem speziell auftritt, wenn das Frontend auf Netlify gehostet ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X