Bien que CORS ait été configuré via API Gateway et que l'en-tête Access-Control-Allow-Origin soit défini, le message d'erreur suivant s'affiche quand je tente d'appeler l'API depuis AJAX dans Chrome:
XMLHttpRequest ne peut pas charger http://XXXXX.execute-api.us-west-2.amazonaws.com/beta/YYYYY . Aucun en-tête 'Access-Control-Allow-Origin' n'est présent sur la ressource demandée. Origin 'null' n'est donc pas autorisé à accéder. La réponse avait le code d'état HTTP 403.
J'ai essayé d'obtenir l'URL via Postman et il montre que l'en-tête ci-dessus est passé avec succès:
Et de la réponse OPTIONS:
Comment puis-je appeler mon API à partir du navigateur sans revenir à JSON-P?
J'ai le même problème. J'ai utilisé 10 heures pour la découverte.
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);
};
Si quelqu'un d'autre se heurte encore à cela, j'ai pu retrouver la cause première de mon application.
Si vous exécutez API-Gateway avec des autorisateurs personnalisés, API-Gateway renverra un message 401 ou 403 avant qu'il ne frappe réellement votre serveur. Par défaut, API-Gateway N'EST PAS configuré pour CORS lors du renvoi 4xx à partir d'un autoriseur personnalisé.
En outre, si vous obtenez un code d'état de 0
ou 1
à partir d'une demande exécutée via API Gateway, c'est probablement votre problème.
Pour corriger - dans la configuration de la passerelle API - allez à "Réponses de la passerelle", développez "4XX par défaut" et ajoutez-y un en-tête de configuration CORS. c'est à dire.
Access-Control-Allow-Origin: '*'
Assurez-vous de redéployer votre passerelle - et le tour est joué!
Mon échantillon a bien fonctionné: j'ai seulement inséré 'Accès-Contrôle-Autoriser-Origine': '*', dans en-têtes: {} dans la fonction nodejs Lambda générée. J'ai apporté no modifications à la couche d'API générée par Lambda.
Voici mon 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 ) {
...
}
};
Voici mon appel AJAX
$.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(); }
});
1) Je devais faire la même chose que @riseres et quelques autres modifications. Voici les en-têtes de ma réponse:
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) Et
Selon cette documentation:
http://docs.aws.Amazon.com/apigateway/latest/developerguide/how-to-cors.html
Lorsque vous utilisez un proxy pour les fonctions lambda dans la configuration d'API Gateway, les méthodes post ou get n'ont pas d'en-têtes ajoutés, mais uniquement les options. Vous devez le faire manuellement dans la réponse (serveur ou réponse lambda).
3) Et
À côté de cela, je devais désactiver l'option 'API Key Required' dans la méthode de publication de ma passerelle API.
Si vous avez tout essayé en vain, vous vous retrouverez comme moi. Il s'avère que les instructions de configuration CORS existantes d'Amazon fonctionnent parfaitement ... assurez-vous simplement que vous n'oubliez pas de redéployer! L’assistant d’édition CORS, même avec toutes ses petites coches vertes, ne met pas à jour en direct votre API. Peut-être évident, mais ça m'a stoppé pendant une demi-journée.
Dans mon cas, j’écrivais simplement l’URL de la requête de récupération erronée. Sur serverless.yml
, vous définissez cors
sur 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}
et ensuite, sur le gestionnaire lambda, vous envoyez les en-têtes, mais si vous effectuez la requête d'extraction de manière erronée sur le serveur, vous n'obtiendrez pas cet en-tête dans la réponse et vous obtiendrez cette erreur. Alors, vérifiez votre URL de demande sur le front.
Le mien a fonctionné après avoir réalisé que l’autorisateur lambda échouait et pour une raison inconnue qui était traduite en une erreur CORS. Un correctif simple à mon autorisateur (et à certains tests d’autoriseurs que j’aurais dû ajouter en premier lieu) et cela a fonctionné. Pour moi, l'action "Activer CORS" de la passerelle API était requise. Cela a ajouté tous les en-têtes et autres paramètres dont j'avais besoin dans mon API.
Dans mon cas, étant donné que j'utilisais AWS_IAM en tant que méthode d'autorisation, je devais accorder des autorisations à mon rôle IAM pour accéder au noeud final.
Je suis en cours d'exécution aws-serverless-express
, et dans mon cas, nécessaire pour éditer simple-proxy-api.yaml
.
Avant que CORS ne soit configuré en https://example.com
, je viens de permuter le nom de mon site et de le redéployer via npm run setup
, et le fichier lambda/pile existant a été mis à jour.
#...
/:
#...
method.response.header.Access-Control-Allow-Origin: "'https://example.com'"
#...
/{proxy+}:
method.response.header.Access-Control-Allow-Origin: "'https://example.com'"
#...
Une autre cause fondamentale de ce problème pourrait être une différence entre HTTP/1.1 et HTTP/2.
Symptôme: Certains utilisateurs, mais pas tous, ont signalé une erreur CORS lors de l'utilisation de notre logiciel.
Problème: L'en-tête Access-Control-Allow-Origin
était manquant parfois .
Contexte: Nous avions un Lambda en place, dédié à la gestion de la demande OPTIONS
et à la réponse avec les en-têtes CORS correspondants, comme Access-Control-Allow-Origin
correspondant à une liste blanche Origin
.
Solution: La passerelle API semble transformer tous les en-têtes en minuscules pour les appels HTTP/2, mais conserve la capitalisation pour HTTP/1.1. Cela a entraîné l'échec de l'accès à event.headers.Origin
.
Vérifiez si vous rencontrez ce problème aussi:
En supposant que votre API se trouve à https://api.example.com
et votre interface frontale à https://www.example.com
. En utilisant CURL, faites une requête en utilisant HTTP/2:
curl -v -X OPTIONS -H 'Origin: https://www.example.com' https://api.example.com
Le résultat de la réponse doit inclure l’en-tête:
< Access-Control-Allow-Origin: https://www.example.com
Répétez la même étape avec HTTP/1.1 (ou avec un en-tête Origin
minuscule):
curl -v -X OPTIONS --http1.1 -H 'Origin: https://www.example.com' https://api.example.com
Si l'en-tête Access-Control-Allow-Origin
est manquant, vous pouvez vérifier la sensibilité à la casse lors de la lecture de l'en-tête Origin
.