Aucun en-tête' Access-Control-Allow-Origin ' n'est présent sur la ressource demandée-lorsque vous essayez d'obtenir des données à partir d'une API REST
j'essaie de récupérer des données de L'API REST de HP Alm. Il fonctionne assez bien avec un petit script curl - je reçois mes données.
fait maintenant cela avec JavaScript, fetch et ES6 (plus ou moins) semble être un plus grand problème. Je n'arrête pas de recevoir ce message d'erreur:
Chercher de l'API ne peut pas charger . La réponse à une demande avant le vol ne vérification du contrôle d'accès: aucun en-tête 'Access-Control-Allow-Origin' n'est présents sur la demande ressources. Origine " http://127.0.0.1:3000 " est donc pas autorisé à accéder. La réponse contenait le code D'état HTTP 501. Si une réponse opaque répond à vos besoins, définissez le mode de la requête à 'no-cors' pour récupérer la ressource avec CORS désactivé.
je comprends que c'est parce que j'essaie de récupérer ces données à l'intérieur de mon hôte local et la solution devrait utiliser CORS. Maintenant je pensais que j'avais vraiment fait ça, mais d'une façon ou d'une autre ignore ce que j'écris dans l'en-tête ou le problème est autre chose?
alors, y a-t-il un problème de mise en œuvre? Suis-je le fais mal? Je ne peux pas vérifier les logs du serveur malheureusement. Je suis vraiment un peu coincé ici.
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));
}
J'utilise du Chrome. J'ai également essayé d'utiliser ce Plugin Chrome CORS, mais ensuite je reçois un autre message d'erreur:
la valeur de l'en-tête 'Access-Control-Allow-Origin' dans la réponse ne doit pas être le Joker ' * ' lorsque le mode d'authentification de la requête est "inclure". Origine " http://127.0.0.1:3000 " n'est donc pas admis accès. Le mode de vérification des pouvoirs XMLHttpRequest est contrôlé par l'attribut withCredentials.
4 réponses
Cette réponse, couvre beaucoup de terrain, il est donc divisé en trois parties:
- Comment éviter le CORS de contrôle en amont
- comment utiliser un proxy CORS pour se déplacer "No Access-Control-Allow-Origin header" problems
- Comment réparer "Access-Control-Allow-Origin-tête ne doit pas être le" générique problèmes
Comment éviter le CORS de contrôle en amont
le code de la question déclenche un" CORS preflight "puisqu'il envoie un en-tête Authorization
.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests
même sans cela, l'en-tête Content-Type: application/json
déclencherait également le vol avant.
Ce "contrôle en amont" moyens: avant que le navigateur tente le POST
dans le code de la question, il faudra d'abord envoyer un OPTIONS
demande au serveur - pour déterminer si le serveur est d'opter pour la réception d'un cross-origin POST
qui comprend le Authorization
et Content-Type: application/json
en-têtes.
cela fonctionne assez bien avec un petit script curl - je reçois mes données.
pour tester correctement avec curl
, vous devez émuler le preflight OPTIONS
demande que le navigateur envoie:
curl -i -X OPTIONS -H "Origin: http://127.0.0.1:3000" \
-H 'Access-Control-Request-Method: POST' \
-H 'Access-Control-Request-Headers: Content-Type, Authorization' \
"https://the.sign_in.url"
... avec https://the.sign_in.url
remplacé par quelque soit votre URL sign_in
.
La réponse que le navigateur a besoin de voir à partir de ce OPTIONS
demande doit inclure les en-têtes comme ceci:
Access-Control-Allow-Origin: http://127.0.0.1:3000
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type, Authorization
si la réponse OPTIONS
n'inclut pas ces en-têtes, alors le navigateur s'arrêtera là et ne tentera jamais d'envoyer le POST
demande. De plus, le code de statut HTTP pour la réponse doit être un 2xx-typiquement 200 ou 204. Si c'est un autre code d'état, le navigateur s'arrêtera là.
le serveur de la question répond à la requête OPTIONS
avec un code d'état 501, ce qui signifie apparemment qu'il essaie d'indiquer qu'il ne prend pas en charge les requêtes OPTIONS
. D'autres serveurs répondent généralement avec une 405 "Méthode non autorisée" code d'état dans cette affaire.
donc vous n'allez jamais être en mesure de faire des requêtes POST
directement à ce serveur à partir de votre code Javascript frontal si le serveur répond à cette requête OPTIONS
avec un 405 ou 501 ou autre qu'un 200 ou 204 ou si ne répond pas avec ces en-têtes de réponse nécessaires.
la façon d'éviter de déclencher un vol avant pour le cas en question serait:
- si le serveur ne nécessite pas
Authorization
en-tête de requête, mais à la place (par exemple) s'est appuyé sur des données d'authentification intégrées dans le corps de la requêtePOST
ou comme paramètre de requête - si le serveur n'a pas besoin du corps
POST
pour avoir un type de médiaContent-Type: application/json
mais a accepté le corpsPOST
commeapplication/x-www-form-urlencoded
avec un paramètre appeléjson
(ou autre) dont la valeur est la donnée JSON
comment utiliser un proxy CORS pour se déplacer "No Access-Control-Allow-Origin header" problems
si vous ne contrôlez pas le serveur auquel votre code JavaScript frontal envoie une requête, et le problème avec la réponse de ce serveur est juste l'absence de l'en-tête Access-Control-Allow-Origin
nécessaire, vous pouvez toujours obtenir des choses à travailler-en faisant la demande par l'intermédiaire d'un proxy CORS. Pour montrer comment cela fonctionne, d'abord voici un certain code qui n'utilise pas de proxy CORS:
const url = "https://example.com"; // site that doesn’t send Access-Control-*
fetch(url)
.then(response => response.text())
.then(contents => console.log(contents))
.catch(() => console.log("Can’t access " + url + " response. Blocked by browser?"))
la raison pour laquelle le bloc catch
est frappé il y a, le navigateur empêche ce code d'accéder à la réponse qui revient de https://example.com
. Et la raison pour laquelle le navigateur fait cela, c'est que la réponse n'a pas l'en-tête de réponse Access-Control-Allow-Origin
.
maintenant, voici exactement le même exemple, mais juste avec un proxy CORS ajouté dans:
const proxyurl = "https://cors-anywhere.herokuapp.com/";
const url = "https://example.com"; // site that doesn’t send Access-Control-*
fetch(proxyurl + url) // https://cors-anywhere.herokuapp.com/https://example.com
.then(response => response.text())
.then(contents => console.log(contents))
.catch(() => console.log("Can’t access " + url + " response. Blocked by browser?"))
Note: Si https://cors-anywhere.herokuapp.com est en baisse ou indisponible lorsque vous l'essayez, puis voir ci-dessous pour savoir comment déployer votre propre CORS Anywhere server à Heroku en seulement 2-3 minutes.
le deuxième extrait de code ci-dessus peut accéder à la réponse avec succès car en prenant L'URL de la requête et en la changeant en https://cors-anywhere.herokuapp.com/https://example.com -en le préfixant simplement avec L'URL du proxy-provoque la requête à passer par ce proxy, qui alors:
- transmet la demande à
https://example.com
. - reçoit la réponse de
https://example.com
. - ajoute l'en-tête
Access-Control-Allow-Origin
à la réponse. - renvoie cette réponse, avec cet en-tête ajouté, au Code frontal demandé.
le le navigateur permet alors au Code frontend d'accéder à la réponse, parce que cette réponse avec l'en-tête de réponse Access-Control-Allow-Origin
est ce que le navigateur voit.
vous pouvez facilement exécuter votre propre mandataire en utilisant le code de https://github.com/Rob--W/cors-anywhere / .
Vous pouvez aussi facilement déployer votre propre mandataire à Heroku en seulement 2-3 minutes, avec 5 commandes:
git clone https://github.com/Rob--W/cors-anywhere.git
cd cors-anywhere/
npm install
heroku create
git push heroku master
après avoir exécuté ces commandes, vous finirez avec votre propre serveur CORS Anywhere tournant à, par exemple, https://cryptic-headland-94862.herokuapp.com / . Ainsi, plutôt que de préfixer L'URL de votre requête avec https://cors-anywhere.herokuapp.com
, préfixez-la avec L'URL de votre propre instance; par exemple, https://cryptic-headland-94862.herokuapp.com/https://example.com .
donc si vous allez à essayer d'utiliser https://cors-anywhere.herokuapp.com, vous trouvez il est en baisse (qui sera parfois), puis envisager d'obtenir un compte Heroku (si vous ne le faites pas déjà) et prendre 2 ou 3 minutes pour faire les étapes ci-dessus pour déployer votre propre CORS Anywhere server sur Heroku.
peu importe, que vous exécutiez votre propre ou utilisez https://cors-anywhere.herokuapp.com ou autre proxy ouvert, Cette solution fonctionnera même si la requête est celle qui déclenche les navigateurs à faire un Preflight CORS OPTIONS
demande-parce que dans ce cas, le mandataire renvoie également les en-têtes Access-Control-Allow-Headers
et Access-Control-Allow-Methods
nécessaires pour rendre le pré-vol réussi.
Comment réparer "Access-Control-Allow-Origin-tête ne doit pas être le" générique problèmes
je reçois un autre message d'erreur:
la valeur de La En-tête 'Access-Control-Allow-Origin' dans la réponse ne doit pas être le Joker ' * ' lorsque le mode d'authentification de la requête est "inclure". Origine " http://127.0.0.1:3000 " n'est donc pas admis accès. Le mode de vérification des pouvoirs XMLHttpRequest est contrôlé par l'attribut withCredentials.
pour une demande qui inclut les justificatifs d'identité, les navigateurs ne laisseront pas votre interface Code JavaScript accédez à la réponse si la valeur de l'en-tête de réponse Access-Control-Allow-Origin
est *
. Au lieu de cela, la valeur dans ce cas doit correspondre exactement à l'origine de votre code frontend, http://127.0.0.1:3000
.
Voir Accrédités, des demandes et des caractères génériques dans le MDN HTTP de contrôle d'accès (SCRO) de l'article.
si vous contrôlez le serveur auquel vous envoyez la requête, alors une façon courante de traiter cela le cas est de configurer le serveur pour prendre la valeur de l'en-tête de requête Origin
, et echo/reflect qui retourne dans la valeur de l'en-tête de réponse Access-Control-Allow-Origin
. Par exemple, avec nginx:
add_header Access-Control-Allow-Origin $http_origin
mais ce n'est qu'un exemple; d'autres systèmes de serveurs (web) fournissent des façons similaires d'afficher les valeurs d'origine.
J'utilise du Chrome. J'ai également essayé d'utiliser que Chrome CORS Plugin
que le plugin Chrome CORS injecte apparemment simplement un en-tête Access-Control-Allow-Origin: *
dans la réponse que le navigateur voit. Si le plugin était plus intelligent, ce qu'il serait en train de faire est de définir la valeur de ce faux Access-Control-Allow-Origin
en-tête de réponse à l'origine réelle de votre code JavaScript frontal, http://127.0.0.1:3000
.
donc évitez d'utiliser ce plugin, même pour les tests. C'est juste une distraction. Si vous voulez tester les réponses que vous obtenez à partir du serveur sans navigateur les filtrant, vous êtes mieux en utilisant curl -H
comme ci-dessus.
autant que le code Javascript frontal pour la demande fetch(…)
dans la question:
headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');
supprimer ces lignes. Les en-têtes Access-Control-Allow-*
sont réponse en-têtes. Vous ne voulez jamais leur envoyer une demande. Le seul effet qui est de déclencher un navigateur pour faire un contrôle en amont.
cette erreur se produit lorsque L'URL du client et L'URL du serveur ne correspondent pas, y compris le numéro de port. Dans ce cas, vous devez activer votre service pour CORS qui est cross origin resource sharing.
si vous hébergez un service de repos de printemps, alors vous pouvez le trouver dans l'article de blog CORS support in Spring Framework .
si vous hébergez un service en utilisant un noeud.js serveur puis
- Arrêter le Nœud.js serveur.
- npm install de la scro
-
Ajouter les lignes suivantes à votre serveur.js
var cors = require('cors') app.use(cors()) // Use this after the variable declaration
utiliser le type de données: "jsonp", fonctionne pour moi.
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