web-dev-qa-db-fra.com

Aucun en-tête 'Access-Control-Allow-Origin' n'est présent sur la ressource demandée + La réponse avait le code d'état HTTP 401

XMLHttpRequest ne peut pas charger http://192.168.1.253:8080/ ... Aucun en-tête 'Access-Control-Allow-Origin' n'est présent sur la ressource demandée. Origin ' http: // localhost: 42 ' n'est donc pas autorisé à accéder. La réponse avait le code d'état HTTP 401.

Erreur assez commune, avec un grand nombre de solutions possibles qui n'ont pas fonctionné. Je comprends (je pense) comment CORS est censé fonctionner et je ne vois aucun problème avec mes en-têtes HTTP, mais cela ne fonctionne toujours pas

De Chrome:

Request URL:http://192.168.1.253:8080/...
Request Method:OPTIONS
Status Code:200 OK
Remote Address:192.168.1.253:8080
Referrer Policy:no-referrer-when-downgrade
Response Headers
Access-Control-Allow-Headers:x-requested-with,accept,content-
type,authorization
Access-Control-Allow-Methods:POST, GET, PUT, PATCH, OPTIONS, DELETE
Access-Control-Allow-Origin:*
Access-Control-Max-Age:3600
Allow:GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Connection:keep-alive
Content-Length:0
Date:Mon, 15 May 2017 21:50:55 GMT
Expires:0
Pragma:no-cache
Server:...
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block
Request Headers
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:authorization,content-type
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
Host:192.168.1.253:8080
Origin:http://localhost:4200
Pragma:no-cache
Referer:http://localhost:4200/...
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 
(KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36

Je crois comprendre que la réponse de OPTIONS a besoin de Access-Control-Allow-Origin en-tête défini et autorise le type de méthode et les valeurs d'en-tête, ce qu'il fait

Pertinent angular ci-dessous. J'ai fait pas mal de combinaisons différentes, avec toutes sortes de choses différentes dans l'en-tête, mais rien ne fonctionne

private getObject<T>(path: string): Promise<T> {
    return this.http.get(SERVER_URL + path, this.authenticationToken())
        .toPromise()
        .then(response => response.json() as T)
        .catch(this.handleError);
}

private authenticationToken() : RequestOptions {
    let login = JSON.parse(sessionStorage.getItem('currentLogin'));
    if (login && login.authenticationToken) {
        let headers = new Headers({ 
            'Authorization': 'Basic ' + login.authenticationToken,
            'Content-type': 'application/json', 
          });
        return new RequestOptions({ headers: headers });
    }
}

J'ai l'impression qu'il me manque quelque chose d'évident mais ça me rend fou, toute aide est appréciée. Notez que cela fonctionne avec une application Ember pré-existante), donc je ne pense pas que ce soit le serveur

9
Lyle Rolleman

La réponse avait le code d'état HTTP 401.

401 indique une erreur d'authentification. Le message d’erreur de la question ne concerne pas la réponse d’une demande de preflight OPTIONS. Il semble plutôt que ce soit pour la demande GET que vous essayez d’envoyer.

Donc, sur la base de ce message d’erreur, il semble que le scénario le plus probable est que la demande de préfecture OPTIONS du navigateur a réussi mais que votre demande GET échoue en raison d’un échec de l’authentification.

Le serveur renvoie donc une page de réponse/erreur 401. Et beaucoup/la plupart des serveurs Web ne sont pas configurés pour envoyer le Access-Control-Allow-Origin en-tête de réponse pour les réponses/pages d’erreur. C’est la seule raison pour laquelle vous recevez également un message indiquant que cet en-tête est manquant.

Mais cet en-tête manquant pour la réponse d'erreur n'est pas la cause de votre problème. au lieu de cela, le 401 est.

Il semble donc que vous souhaitiez probablement comprendre pourquoi le serveur a envoyé une réponse 401 - pourquoi vous obtenez un échec d’authentification. Si vous corrigez ce problème, il est probable que vous obtiendrez une réponse du serveur incluant le Access-Control-Allow-Origin en-tête de réponse comme prévu.

11
sideshowbarker

Ceci est une erreur typique rencontrée lorsque nous travaillons avec Angular et Ionic, le problème se pose car, lorsque votre application chargée dans un navigateur de votre application charge tout le contenu d'un Origine qui provient de votre adresse locale http://localhost:4200, Puis lorsque vous souhaitez effectuer une demande AJAX envoyée à un autre hôte que localhost:4200 La demande est appelée depuis un point quelconque différent de Origine il nécessite un [~ # ~] cors [~ # ~] (demande de contrôle en amont par partage de ressources d'origine croisée) pour voir si elle peut accéder à la ressource.

La solution consiste à utiliser un proxy pour le backend, ce qui vous permet de détourner certaines URL et de les envoyer à un serveur backend. La mise en place est facile:

1.- Créez un fichier proxy.conf.js Dans le dossier racine de votre projet.

2.- Configurez votre proxy, dans votre fichier proxy.conf.js, En supposant que votre nouvel hôte soit dans http://localhost:3000.

const PROXY_CONFIG = [
    {
        context: [
            "/my",
            "/many",
            "/endpoints",
            "/i",
            "/need",
            "/to",
            "/proxy"
        ],
        target: "http://localhost:3000",
        secure: false
    }
]

module.exports = PROXY_CONFIG;

3.- Modifiez votre fichier package.json En insérant ce "start": "ng serve --proxy-config proxy.conf.js",

4.- Dans votre service, changez un peu le chemin de votre demande de ce http://localhost:3000/endpoints/any/path/that/you/use À ce ../endpoints/any/path/that/you/use (En supposant qu'un autre hôte est dans localhost:3000 Et que le contexte est /endpoints).

5.- Exécuter angular depuis le dossier racine avec: npm start; Ceci exécute ng serve Avec les paramètres de proxy.

Si vous avez besoin de plus d’informations à ce sujet, veuillez vérifier Proxy to backend Angular Cli)

9
havelino