API Gateway CORS: Kein Header 'Access-Control-Allow-Origin'

94

Obwohl CORS über API Gateway eingerichtet wurde und der Access-Control-Allow-OriginHeader festgelegt ist, wird beim Versuch, die API von AJAX in Chrome aus aufzurufen, immer noch die folgende Fehlermeldung angezeigt:

XMLHttpRequest kann http://XXXXX.execute-api.us-west-2.amazonaws.com/beta/YYYYY nicht laden . In der angeforderten Ressource ist kein Header 'Access-Control-Allow-Origin' vorhanden. Origin 'null' ist daher kein Zugriff gestattet. Die Antwort hatte den HTTP-Statuscode 403.

Ich habe versucht, die URL über Postman abzurufen, und es wird angezeigt, dass der obige Header erfolgreich übergeben wurde:

Übergebene Header

Und aus der Antwort von OPTIONS:

Antwortheader

Wie kann ich meine API über den Browser aufrufen, ohne zu JSON-P zurückzukehren?

Tyler
quelle
Haben Sie es auf dem S3 eingerichtet? Wenn ja, könnten Sie das aufstellen Bucket Policy?
Stellen
9
API Gateway-Team hier ... Wenn Sie die Funktion "CORS aktivieren" in der Konsole verwenden, sollte die Konfiguration korrekt sein. Ich gehe davon aus, dass Sie in dem vom Browser ausgeführten JavaScript nicht den richtigen Ressourcenpfad in Ihrer API aufrufen. Wenn Sie versuchen, einen API-Aufruf für eine nicht vorhandene Methode / Ressource / Stufe durchzuführen, erhalten Sie eine generische 403 mit keinem der CORS-Header. Ich sehe nicht ein, wie der Browser den Access-Control-Allow-Origin-Header übersehen könnte, wenn Sie die richtige Ressource aufrufen, da der OPTIONS-Aufruf in Postman eindeutig alle richtigen CORS-Header enthält.
Jackko
1
@ RyanG-AWS Der Client signiert die Anforderung nicht, da die API durch die von ihm aufgerufene Ressource mithilfe eines benutzerspezifischen Tokens authentifiziert wird, sodass die Anmeldeinformationen keine Rolle spielen. Ich kann die API aufrufen, indem ich die URL direkt im Browser besuche, und ich erhalte die entsprechende Antwort.
Tyler
1
@makinbacon: Hast du eine Lösung dafür gefunden? Ich gehe hier das gleiche Problem durch.
Nirmal
1
Meine Methoden und Stufen wurden automatisch von Lambda generiert. Ich habe CORS nachträglich aktiviert. Gleiche Fehler wie OP. Ich habe das automatisch generierte Material weggeblasen, eine neue API und neue Methoden erstellt, auf einer neuen Stufe bereitgestellt und es hat gut funktioniert.
Verbrühung

Antworten:

108

Ich habe das gleiche Problem. Ich habe 10 Stunden benutzt, um herauszufinden.

https://serverless.com/framework/docs/providers/aws/events/apigateway/

// handler.js

'use strict';

module.exports.hello = function(event, context, callback) {

const response = {
  statusCode: 200,
  headers: {
    "Access-Control-Allow-Origin" : "*", // Required for CORS support to work
    "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS 
  },
  body: JSON.stringify({ "message": "Hello World!" })
};

callback(null, response);
};
Riseres
quelle
Das Problem, das ich auch hatte, wurde behoben. Vielen Dank für Ihre Antwort!
Eric Brown
Ich benutze nicht serverlos, aber das hat mein Problem gelöst. Vermutlich müssen Sie diese Header von der eigentlichen Quelle weitergeben.
Costa
2
Zu Ihrer Information, es gibt ein Problem mit dem hier vorgestellten Beispiel. Wenn Sie "Access-Control-Allow-Credentials" haben: true, können Sie den Platzhalter * für Access-Control-Allow-Origin nicht haben. Diese Regel wird vom Browser durchgesetzt. Siehe hier und hier
Kevin
1
Dies funktioniert nicht. Zeigt erneut den gleichen Fehler an. Anforderungsheaderfeld Zugriffskontrolle-Zulassen-Anmeldeinformationen werden von Access-Control-Zulassen-Headern in der Preflight-Antwort nicht zugelassen.
Mitesh7172
Wie können Sie dies mit der Java-Klasse RequestHandler <RequestClass, ResponseClass> tun?
Snedden27
103

Wenn noch jemand darauf stößt, konnte ich die Grundursache in meiner Anwendung ausfindig machen.

Wenn Sie API-Gateway mit benutzerdefinierten Autorisierern ausführen, sendet API-Gateway einen 401 oder 403 zurück, bevor er tatsächlich auf Ihren Server gelangt. Standardmäßig ist API-Gateway NICHT für CORS konfiguriert, wenn 4xx von einem benutzerdefinierten Autorisierer zurückgegeben wird.

Auch - wenn Sie zufällig einen Statuscode von 0oder 1von einer Anforderung erhalten, die über API Gateway ausgeführt wird, ist dies wahrscheinlich Ihr Problem.

Um dies zu beheben, gehen Sie in der API-Gateway-Konfiguration zu "Gateway-Antworten", erweitern Sie "Standard 4XX" und fügen Sie dort einen CORS-Konfigurationsheader hinzu. dh

Access-Control-Allow-Origin: '*'

Stellen Sie sicher, dass Sie Ihr Gateway erneut bereitstellen - und voila!

Gabriel Doty
quelle
7
ich liebe dich. Ich arbeite seit zwei Tagen ernsthaft daran.
efong5
4
Für diejenigen, die dies mit der AWS CLI tun möchten, verwenden Sie:aws apigateway update-gateway-response --rest-api-id "XXXXXXXXX" --response-type "DEFAULT_4XX" --patch-operations op="add",path="/responseParameters/gatewayresponse.header.Access-Control-Allow-Origin",value='"'"'*'"'"'
Will
1
Ich verwende keine benutzerdefinierten Autorisierer und benötige diese weiterhin, da meine Anfrage einen schlechten JSON enthält - danke!
Force Hero
9
Hinweis für mich - vergessen Sie nicht, die API danach
bereitzustellen
2
Seltsam, das hat bei mir funktioniert, aber ich musste nicht neu bereitstellen. Ich habe früher versucht, erneut bereitzustellen. Ich bin mir nicht sicher, warum es bei mir funktioniert hat.
Michael
19

1) Ich musste dasselbe tun wie @riseres und einige andere Änderungen. Dies sind meine Antwortheader:

headers: {
            'Access-Control-Allow-Origin' : '*',
            'Access-Control-Allow-Headers':'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token',
            'Access-Control-Allow-Credentials' : true,
            'Content-Type': 'application/json'
        }

2 und

Nach dieser Dokumentation:

http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html

Wenn Sie in der API-Gateway-Konfiguration einen Proxy für Lambda-Funktionen verwenden, werden den Post- oder Get-Methoden keine zusätzlichen Header hinzugefügt, sondern nur die Optionen. Sie müssen dies manuell in der Antwort tun (Server- oder Lambda-Antwort).

3) Und

Außerdem musste ich die Option "API-Schlüssel erforderlich" in meiner API-Gateway-Post-Methode deaktivieren.

Carlos Alberto Schneider
quelle
4
Ja, ich denke, das Feinste, was viele von uns anfangs vermissen, ist, dass Sie, sobald Sie Ihre API-Gateway-Integration für die Lambda-Funktion mit "Lambda-Proxy-Integration verwenden" konfiguriert haben, tun müssen, was Sie und andere angeben, und sicherstellen, dass die Header hinzugefügt werden programmatisch in der Antwort Ihres Lambda. Das Auto-Gen-Material, das durch "Aktivieren von CORS" auf einem API-Gateway und das Erstellen eines OPTIONS-Responders erstellt wird, ist großartig, bringt Sie jedoch nicht vollständig dorthin, wenn Sie in der Integrationsanforderung innerhalb der API "Lambda-Proxy-Integration verwenden" festlegen Tor.
1
Dies hat bei mir funktioniert ... nachdem ich das Handbuch richtig gelesen habe: Wichtig Wenn Sie die obigen Anweisungen auf die ANY-Methode in einer Proxy-Integration anwenden, werden keine zutreffenden CORS-Header festgelegt. Stattdessen muss Ihr Backend die entsprechenden CORS-Header zurückgeben, z. B. Access-Control-Allow-Origin. docs.aws.amazon.com/apigateway/latest/developerguide/…
BennyHilarious
13

Wenn Sie alles in Bezug auf dieses Problem ohne Erfolg versucht haben, werden Sie dort landen, wo ich es getan habe. Es stellt sich heraus, dass die vorhandenen CORS-Setup-Anweisungen von Amazon einwandfrei funktionieren. Denken Sie daran, die Bereitstellung erneut durchzuführen . Der CORS-Bearbeitungsassistent führt trotz all seiner netten kleinen grünen Häkchen keine Live-Aktualisierungen Ihrer API durch. Vielleicht offensichtlich, aber es hat mich einen halben Tag lang verblüfft.

Geben Sie hier die Bildbeschreibung ein

lase
quelle
Das war's. Ich arbeite buchstäblich zwei Tage daran. Nicht sicher, ob die Logik nach dem Bearbeiten des Gateways nicht mindestens zu einer erneuten Bereitstellung auffordert.
Chris Christensen
@ChrisChristensen froh, dass Sie es herausgefunden haben - es gibt immer etwas so Erleichterndes und doch unglaublich Besiegendes
lase
Dies ist die Antwort, die im Jahr 2020 gültig ist. Danke
Rahul Khanna
RE-DEPLOY RE-DPLOY RE-DEPLOY
Surjith SM
11

Haben Sie meine Probe Arbeits: Ich gerade eingefügt 'Access-Control-Allow-Origin': '*', innen Header: {} in der NodeJS Lambda - Funktion erzeugt. Ich habe keine Änderungen an der von Lambda generierten API-Schicht vorgenommen.

Hier ist mein NodeJS:

'use strict';
const doc = require('dynamodb-doc');
const dynamo = new doc.DynamoDB();
exports.handler = ( event, context, callback ) => {
    const done = ( err, res ) => callback( null, {
        statusCode: err ? '400' : '200',
        body: err ? err.message : JSON.stringify(res),
        headers:{ 'Access-Control-Allow-Origin' : '*' },
    });
    switch( event.httpMethod ) {
        ...
    }
};

Hier ist mein AJAX-Anruf

$.ajax({
    url: 'https://x.execute-api.x-x-x.amazonaws.com/prod/fnXx?TableName=x',
    type: 'GET',
    beforeSend: function(){ $( '#loader' ).show();},
    success: function( res ) { alert( JSON.stringify(res) ); },
    error:function(e){ alert('Lambda returned error\n\n' + e.responseText); },
    complete:function(){ $('#loader').hide(); }
});
MannyC
quelle
Ich habe festgestellt, dass viele Dokumentationen von Amazon selbst mit dem Pfadfragment "../latest/ .." veraltet sind. Nachdem vor ungefähr einer Woche alles verschrottet worden war, zeigte der CORS-Knopf plötzlich an, dass er richtig funktioniert. Die API hat die "ANY" -Methode automatisch erstellt und die CORS-Schaltfläche hat die "OPTIONS" -Methode automatisch erstellt. Ich habe der API nichts hinzugefügt. Das obige "GET" funktioniert und ich habe seitdem einen Ajax "POST" hinzugefügt, der auch funktioniert, ohne dass ich die API berühre.
MannyC
Ich habe fast zwei Stunden damit verbracht, herauszufinden, wie Access-Control-Allow-Origin mithilfe der AWS-Konsole zur Methodenantwort hinzugefügt werden kann, aber dies war auch das einzige, was für mich funktioniert hat.
Shn_Android_Dev
8

Für Googler:

Hier ist warum:

  • Eine einfache Anfrage oder GET/ POSTohne Cookies löst keinen Preflight aus
  • Wenn Sie CORS für einen Pfad zu konfigurieren, API - Gateway wird nur eine erstellen OPTIONSMethode für diesen Pfad, dann senden Allow-OriginHeader mit Mock - Antworten , wenn die Benutzer Anrufe OPTIONS, aber GET/ POSTnicht erhalten Allow-Originautomatisch
  • Wenn Sie versuchen, einfache Anforderungen mit aktiviertem CORS-Modus zu senden, wird eine Fehlermeldung angezeigt, da diese Antwort keinen Allow-OriginHeader enthält
  • Sie können sich an bewährte Methoden halten. Einfache Anfragen sind nicht dazu gedacht, eine Antwort an den Benutzer zu senden, Authentifizierung / Cookie zusammen mit Ihren Anfragen zu senden, um dies "nicht einfach" zu machen, und Preflight wird ausgelöst
  • Für die folgende Anfrage müssen Sie jedoch selbst CORS-Header senden OPTIONS

Etwas zusammenfassen:

  • Nur harmlos OPTIONSwird automatisch von API Gateway generiert
  • OPTIONSwerden vom Browser nur als Vorsichtsmaßnahme verwendet, um die Möglichkeit von CORS auf einem Pfad zu überprüfen
  • Ob CORS akzeptiert wird, hängt von der tatsächlichen Methode ab, z GET.POST
  • Sie müssen in Ihrer Antwort manuell die entsprechenden Header senden
theaws.blog
quelle
5

Ich habe darin eine einfache Lösung gefunden

API-Gateway> Wählen Sie Ihren API-Endpunkt aus> Wählen Sie die Methode aus (in meinem Fall war es der POST).

Jetzt gibt es ein Dropdown-Menü AKTIONEN> CORS aktivieren. Wählen Sie es aus.

Wählen Sie nun erneut die Dropdown-Liste AKTIONEN> API bereitstellen (erneut bereitstellen).

Geben Sie hier die Bildbeschreibung ein

Es funktionierte !

Ravi Ram
quelle
Warum wird diese Antwort abgelehnt, aber es gibt unten andere ähnliche Antworten?
Dinesh Kumar
Für das Aufrufen eines AWS-basierten API-Gateways funktioniert diese Lösung
ewalel
4

Ich habe gerade Header zu meiner Lambda-Funktionsantwort hinzugefügt und es hat wie ein Zauber funktioniert

exports.handler = async (event) => {
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hey it works'),
        headers:{ 'Access-Control-Allow-Origin' : '*' }
    };
    return response;
};
Vishal Shetty
quelle
3

Ich habe meine zum Laufen gebracht, nachdem ich festgestellt hatte, dass der Lambda-Autor fehlgeschlagen war und aus einem unbekannten Grund in einen CORS-Fehler übersetzt wurde. Eine einfache Lösung für meinen Autorisierer (und einige Autorisierertests, die ich eigentlich hätte hinzufügen sollen) und es hat funktioniert. Für mich war die API-Gateway-Aktion 'CORS aktivieren' erforderlich. Dadurch wurden alle Header und anderen Einstellungen hinzugefügt, die ich in meiner API benötigte.

RodP
quelle
und erneut bereitstellen! :)
Robin C Samuel
2

Nach dem Ändern Ihrer Funktion oder Ihres Codes Befolgen Sie diese beiden Schritte.

Zuerst aktivieren CORS Dann API bereitstellen jedes Mal.

Ankit Kumar Rajpoot
quelle
Danke für das. Das "CORS aktivieren" in der Ressource wurde nicht bemerkt. Ich habe den Verstand verloren.
Shlomi Bazel
2

Bereitstellung des Codes nach Aktivierung von CORS für beide POSTund OPTIONSArbeit für mich.

Ziaur Rahman
quelle
1
Vielen Dank für Ihren Beitrag. Können Sie jedoch erklären, warum es bei Ihnen funktioniert hat? Ich lade Sie ein, diesen Leitfaden zu lesen, um Ihre Antwort zu verbessern: "Wie ich eine gute Antwort schreibe" hier: stackoverflow.com/help/how-to-answer
Guillaume Raymond
2

Für mich war die Antwort, die ENDLICH ARBEITET hat, der Kommentar von James Shapiro aus Alex Rs Antwort (am zweithäufigsten bewertet). Ich bin in erster Linie auf dieses API-Gateway-Problem gestoßen, indem ich versucht habe, eine in S3 gehostete statische Webseite zu erstellen, auf der die Kontaktseite mit Lambda verarbeitet und eine E-Mail gesendet werden kann. Durch einfaches Überprüfen von [] Default 4XX wurde die Fehlermeldung behoben.

Geben Sie hier die Bildbeschreibung ein

Jason
quelle
1

Ich laufe aws-serverless-expressund musste in meinem Fall bearbeiten simple-proxy-api.yaml.

Bevor CORS konfiguriert wurde https://example.com, habe ich einfach den Namen meiner Site getauscht und über erneut bereitgestellt npm run setup, und mein vorhandenes Lambda / Stack wurde aktualisiert.

#...
/:
#...
method.response.header.Access-Control-Allow-Origin: "'https://example.com'"
#...
/{proxy+}:
method.response.header.Access-Control-Allow-Origin: "'https://example.com'"
#...
James L.
quelle
1

In meinem Fall musste ich, da ich AWS_IAM als Autorisierungsmethode für API Gateway verwendet habe, meine IAM-Rollenberechtigungen erteilen, um den Endpunkt zu erreichen.

CamHart
quelle
2
Mann bin ich froh, dass ich diesen Kommentar hinterlassen habe. Das passiert mir immer wieder: D.
CamHart
Ich liebe es, meine eigene Lösung für ein zukünftig wiederkehrendes Problem zu finden.
Zac Grierson
0

Eine weitere Hauptursache für dieses Problem könnte ein Unterschied zwischen HTTP / 1.1 und HTTP / 2 sein.

Symptom: Einige Benutzer, nicht alle, haben bei Verwendung unserer Software einen CORS-Fehler gemeldet.

Problem: Der Access-Control-Allow-OriginHeader fehlte manchmal .

Kontext: Wir hatten ein Lambda eingerichtet, das sich der Bearbeitung von OPTIONSAnfragen und der Beantwortung der entsprechenden CORS-Header widmete , z. B. dem Access-Control-Allow-OriginAbgleichen einer Whitelist Origin.

Lösung: Das API-Gateway scheint alle Header für HTTP / 2-Aufrufe in Kleinbuchstaben umzuwandeln, behält jedoch die Großschreibung für HTTP / 1.1 bei. Dies führte dazu, dass der Zugriff event.headers.originfehlschlug.

Überprüfen Sie, ob Sie auch dieses Problem haben:

Angenommen, Ihre API befindet sich unter https://api.example.comund Ihr Front-End unter https://www.example.com. Stellen Sie mit CURL eine Anfrage über HTTP / 2:

curl -v -X OPTIONS -H 'Origin: https://www.example.com' https://api.example.com

Die Antwortausgabe sollte den Header enthalten:

< Access-Control-Allow-Origin: https://www.example.com

Wiederholen Sie denselben Schritt mit HTTP / 1.1 (oder mit einem Kleinbuchstaben Origin):

curl -v -X OPTIONS --http1.1 -H 'Origin: https://www.example.com' https://api.example.com

Wenn die Access-Control-Allow-OriginKopfzeile fehlt, sollten Sie beim Lesen der OriginKopfzeile die Groß- und Kleinschreibung überprüfen .

Michael Seibt
quelle
0

Neben anderen Kommentaren sollten Sie auch auf den Status achten, der von Ihrer zugrunde liegenden Integration zurückgegeben wird, und darauf, ob der Header Access-Control-Allow-Origin für diesen Status zurückgegeben wird.

Wenn Sie "CORS aktivieren" ausführen, wird nur der Status 200 festgelegt. Wenn Sie andere auf dem Endpunkt haben, z. B. 4xx und 5xx, müssen Sie den Header selbst hinzufügen.

Nigel Atkinson
quelle
-1

Manchmal verursacht das Lambda-Timeout einen CORS-Fehler. Sie können das Zeitlimit erhöhen, um das Problem zu beheben. Dies kann das Problem beheben. Es repariert meine.

Geben Sie hier die Bildbeschreibung ein

Rafsan Uddin Beg Rizan
quelle
-2

In meinem Fall habe ich einfach die URL der Abrufanforderung falsch geschrieben. Ein serverless.yml, Sie setzen corsauf true:

register-downloadable-client:
    handler: fetch-downloadable-client-data/register.register
    events:
      - http:
          path: register-downloadable-client
          method: post
          integration: lambda
          cors: true
          stage: ${self:custom.stage}

und dann senden Sie auf dem Lambda-Handler die Header, aber wenn Sie die Abrufanforderung im Frontend falsch machen, erhalten Sie diesen Header nicht in der Antwort und Sie erhalten diesen Fehler. Überprüfen Sie daher Ihre Anforderungs-URL auf der Vorderseite.

Ericson Willians
quelle
-3

In Python können Sie dies wie im folgenden Code tun:

{ "statusCode" : 200,
'headers': 
    {'Content-Type': 'application/json',
    'Access-Control-Allow-Origin': "*"
     },
"body": json.dumps(
    {
    "temperature" : tempArray,
    "time": timeArray
    })
 }
Mukesh Arya
quelle