javascript - with - xmlhttprequest no-cors




In der angeforderten Ressource ist kein 'Access-Control-Allow-Origin'-Header vorhanden, wenn versucht wird, Daten von einer REST-API abzurufen (5)

Ich versuche, einige Daten aus der REST-API von HP Alm abzurufen. Es funktioniert ziemlich gut mit einem kleinen Curl-Skript - ich bekomme meine Daten.

Jetzt scheint es ein größeres Problem zu sein, dies mit JavaScript, Fetch und ES6 (mehr oder weniger) zu tun. Ich erhalte immer wieder folgende Fehlermeldung:

Abruf-API kann nicht geladen werden. Die Antwort auf die Preflight-Anforderung besteht die Zugriffskontrollprüfung nicht: In der angeforderten Ressource ist kein Header 'Zugriffskontrolle-Zulassen-Ursprung' vorhanden. Origin ' http://127.0.0.1:3000 ' ist daher kein Zugriff gestattet. Die Antwort hatte den HTTP-Statuscode 501. Wenn eine undurchsichtige Antwort Ihren Anforderungen entspricht, setzen Sie den Anforderungsmodus auf 'no-cors', um die Ressource mit deaktiviertem CORS abzurufen.

Ich verstehe, dass dies daran liegt, dass ich versuche, diese Daten von meinem lokalen Host abzurufen, und dass die Lösung CORS verwenden sollte. Jetzt dachte ich, ich hätte das tatsächlich getan, aber irgendwie ignoriert es entweder, was ich in den Header schreibe, oder ist das Problem etwas anderes?

Gibt es ein Implementierungsproblem? Mache ich es falsch? Ich kann die Server Logs leider nicht überprüfen. Ich stecke hier wirklich ein bisschen fest.

function performSignIn() {

  let headers = new Headers();

  headers.append('Content-Type', 'application/json');
  headers.append('Accept', 'application/json');

  headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
  headers.append('Access-Control-Allow-Credentials', 'true');

  headers.append('GET', 'POST', 'OPTIONS');

  headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));

  fetch(sign_in, {
      //mode: 'no-cors',
      credentials: 'include',
      method: 'POST',
      headers: headers
    })
    .then(response => response.json())
    .then(json => console.log(json))
    .catch(error => console.log('Authorization failed : ' + error.message));
}

Ich benutze Chrome. Ich habe auch versucht, dieses Chrome CORS-Plugin zu verwenden, aber dann wird eine andere Fehlermeldung angezeigt:

Der Wert des Headers 'Access-Control-Allow-Origin' in der Antwort darf nicht der Platzhalter '*' sein, wenn der Anmeldeinformationsmodus der Anforderung 'include' ist. Origin ' http://127.0.0.1:3000 ' ist daher kein Zugriff gestattet. Der Anmeldeinformationsmodus von Anforderungen, die von XMLHttpRequest initiiert werden, wird vom withCredentials-Attribut gesteuert.


Das Problem trat auf, weil Sie den folgenden Code als Anforderungsheader in Ihrem Front-End hinzugefügt haben:

headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');

Diese Header gehören zur Antwort , nicht zur Anfrage. Also entferne sie, einschließlich der Zeile:

headers.append('GET', 'POST', 'OPTIONS');

Ihre Anfrage hatte 'Content-Type: application / json' und löste daher den sogenannten CORS-Preflight aus. Dies führte dazu, dass der Browser die Anforderung mit der Methode OPTIONS sendete. Ausführliche Informationen finden Sie unter CORS-Preflight .
Daher müssen Sie in Ihrem Back-End diese Preflight-Anforderung bearbeiten, indem Sie die Antwortheader zurückgeben, die Folgendes enthalten:

Access-Control-Allow-Origin : http://localhost:3000
Access-Control-Allow-Credentials : true
Access-Control-Allow-Methods : GET, POST, OPTIONS
Access-Control-Allow-Headers : Origin, Content-Type, Accept

Die tatsächliche Syntax hängt natürlich von der Programmiersprache ab, die Sie für Ihr Back-End verwenden.

In Ihrem Frontend sollte es so aussehen:

function performSignIn() {
    let headers = new Headers();

    headers.append('Content-Type', 'application/json');
    headers.append('Accept', 'application/json');
    headers.append('Authorization', 'Basic ' + base64.encode(username + ":" +  password));
    headers.append('Origin','http://localhost:3000');

    fetch(sign_in, {
        mode: 'cors',
        credentials: 'include',
        method: 'POST',
        headers: headers
    })
    .then(response => response.json())
    .then(json => console.log(json))
    .catch(error => console.log('Authorization failed : ' + error.message));
}

Die Verwendung von dataType: 'jsonp' hat bei mir funktioniert.

   async function get_ajax_data(){
       var _reprojected_lat_lng = await $.ajax({
                                type: 'GET',
                                dataType: 'jsonp',
                                data: {},
                                url: _reprojection_url,
                                error: function (jqXHR, textStatus, errorThrown) {
                                    console.log(jqXHR)
                                },
                                success: function (data) {
                                    console.log(data);

                                    // note: data is already json type, you
                                    //       just specify dataType: jsonp
                                    return data;
                                }
                            });


 } // function               

Dieser Fehler tritt auf, wenn die Client-URL und die Server-URL nicht übereinstimmen, einschließlich der Portnummer. In diesem Fall müssen Sie Ihren Dienst für CORS aktivieren, bei dem es sich um die gemeinsame Nutzung von Ressourcen aus verschiedenen Quellen handelt.

Wenn Sie einen Spring REST-Service hosten, finden Sie ihn im Blogbeitrag CORS-Support in Spring Framework .

Wenn Sie einen Dienst mit einem Node.js-Server hosten, dann

  1. Stoppen Sie den Node.js-Server.
  2. npm install cors --save
  3. Fügen Sie Ihrem server.js die folgenden Zeilen hinzu

    var cors = require('cors')
    
    app.use(cors()) // Use this after the variable declaration

Entferne das:

credentials: 'include',

Nur meine zwei Cent ... in Bezug auf die Verwendung eines CORS-Proxys, um Probleme mit dem Header "Keine Access-Control-Allow-Origin " zu umgehen

Für diejenigen unter Ihnen, die mit PHP im Backend arbeiten, ist die Bereitstellung eines "CORS-Proxys" so einfach wie:

  1. erstelle eine datei namens 'no-cors.php' mit folgendem inhalt:

    $URL = $_GET['url']; echo json_encode(file_get_contents($URL)); die();

  2. Mach auf deinem Frontend so etwas wie:

    fetch('https://example.com/no-cors.php' + '?url=' + url) .then(response=>{*/Handle Response/*})





preflight