Je sais donc qu'il existe de nombreux articles CORS et je ne fais que les ajouter, mais je ne trouve aucune réponse qui puisse m'aider. Je construis donc une application Angular 4 qui s'appuie sur mon API php. Fonctionne localement sans problème, lorsque je le lance sur le domaine avec l'API située à l'adresse app.example.com
的应用程序和位于 api.example.com
, je n'arrive pas à me connecter car j'obtiens l'erreur suivante :
XMLHttpRequest ne peut pas charger http://api.example.com/Account/Login. La réponse à la demande de contrôle en amont a échoué au contrôle du contrôle d'accès : non En-tête 'Access-Control-Allow-Origin' présent dans la requête Ressource. La source "http://app.example.com" n'est donc pas autorisée accéder.
Mon code php ressemble à ceci :
$http_origin = $_SERVER['HTTP_ORIGIN']; $allowed_domains = array( 'http://example.com', 'https://example.com', 'http://app.example.com', 'https://app.example.com', 'http://www.example.com', 'https://www.example.com' ); if (in_array(strtolower($http_origin), $allowed_domains)) { // header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Origin: $http_origin"); header('Access-Control-Allow-Credentials: true'); header('Access-Control-Max-Age: 86400'); } // Access-Control headers are received during OPTIONS requests if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); header("Access-Control-Allow-Headers: Authorization, Content-Type,Accept, Origin"); exit(0); }
Mon post Angular ressemble à ceci :
public login(login: Login): Observable<LoginResponse> { let headers = new Headers(); headers.append('Content-Type', 'application/x-www-form-urlencoded'); headers.append('Authorization', 'Basic ' + btoa(login.Username + ':' + login.Password)); return this.http.post(this.apiBaseUrl + '/Account/Login', "grant_type=client_credentials", { headers: headers }) .map(response => { // code }); }
Si j'exécute la requête via Postman (cela n'affecte pas CORS), j'obtiens :
{ "error": "invalid_client", "error_description": "Client credentials were not found in the headers or body" }
J'ai essayé de définir origin sur '*
' juste pour tester et voir si c'était le cœur du problème, mais cela a toujours échoué de la même manière.
Modifier Juste une mise à jour avec les informations ci-dessous. Changer la casse dans l'en-tête n'a aucun effet, et extraire le code de l'instruction if n'a aucun effet non plus.
J'ai débogué PHP en disant à mon application en direct d'accéder à l'API locale et PHP fonctionne comme prévu. Il définit l'en-tête et le place dans chaque instruction if.
Edit Shot 2 J'ai vraiment besoin d'aide et si quelqu'un a des idées, je l'apprécierais vraiment.
Edit Shot 3 Si je définis tous les éléments d'en-tête dans .htaccess au lieu de php, cela me laisse passer. Cependant, je suis maintenant coincé avec l'erreur répertoriée ci-dessus, qui est l'erreur que j'obtiens toujours lorsque j'utilise Postman, mais maintenant lorsque j'utilise le site Web lui-même.
{"error":"invalid_client","error_description":"在标头或正文中找不到客户端凭据"}
Mes en-têtes de réponse ressemblent à ceci
Access-Control-Allow-Credentials:true Access-Control-Allow-Headers:authorization, content-type, accept, origin Access-Control-Allow-Methods:GET, POST, OPTIONS Access-Control-Allow-Origin:*
Une fois que cela fonctionnera, je le changerai de * en uniquement mon domaine. Mais maintenant je le laisse comme *.
Mon en-tête sur demande.
Dans mon cas similaire, le frontend Angular et le backend Php m'ont aidé avec le code ci-dessous. J'envoie d'abord un en-tête :
Après eux, je peux ignorer les demandes d'options :
Cette approche m'a aidé à gérer les méthodes de requête intégrées « publier » et « supprimer » dans Angular.
D'accord, j'ai eu un problème similaire récemment et j'ai tout résolu uniquement sur le backend, sans les éléments .htaccess.
Lorsque le navigateur envoie une requête inter-serveur, il envoie d'abord une requête OPTIONS pour s'assurer qu'elle est valide et qu'une "vraie" requête peut être envoyée. La "vraie" requête est envoyée lorsqu'elle obtient une réponse correcte et valide d'OPTIONS.
Maintenant, pour les deux requêtes sur le backend, vous devez vous assurer que les en-têtes corrects sont renvoyés : content-type,allow-origin,allow-headers, etc...
Assurez-vous que dans les requêtes OPTIONS sur le backend, l'application renvoie l'en-tête et renvoie une réponse au lieu de continuer le flux complet de l'application.
Dans une "vraie" requête, vous devez renvoyer les en-têtes corrects et le corps de réponse régulier.
Exemple :
Ce qu'il faut retenir :
Si vous utilisez : "Access-Control-Allow-Credentials" = true Assurez-vous que « Access-Control-Allow-Origin » n'est pas « * », il doit être défini sur le bon domaine ! (Beaucoup de sang a coulé ici :/)
Définissez les en-têtes autorisés que vous obtiendrez dans "Access-Control-Allow-Headers" Si vous ne les définissez pas, la requête échouera