CORS : PHP : échec de la réponse à la demande de contrôle en amont. J'autorise l'origine
P粉642920522
P粉642920522 2023-08-24 18:24:56
0
2
673
<p>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'application sur <code>app.example.com</code> et l'API sur <code>api.example.com</code> je transmets mon identifiant car j'obtiens l'erreur suivante : </p> <blockquote> <p>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.</p> </blockquote> <p>我的 php 代码如下所示:</p> <pre class="brush:php;toolbar:false;">$http_origin = $_SERVER['HTTP_ORIGIN']; $allowed_domains = tableau( 'http://exemple.com', 'https://exemple.com', 'http://app.exemple.com', 'https://app.exemple.com', 'http://www.exemple.com', 'https://www.exemple.com' ); if (in_array(strtolower($http_origin), $allowed_domains)) { // en-tête("Access-Control-Allow-Origin: *"); en-tête("Access-Control-Allow-Origin : $http_origin"); en-tête('Access-Control-Allow-Credentials : vrai'); en-tête('Access-Control-Max-Age: 86400'); } // Les en-têtes Access-Control sont reçus lors des requêtes OPTIONS si ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { header("Access-Control-Allow-Methods : GET, POST, OPTIONS"); header("Access-Control-Allow-Headers : Autorisation, Content-Type, Accept, Origin"); sortie(0); }</pré> <p>我的 Angular 帖子如下所示:</p> <pre class="brush:php;toolbar:false;">connexion publique (connexion : connexion) : observable<LoginResponse> { let en-têtes = nouveaux en-têtes(); headers.append('Content-Type', 'application/x-www-form-urlencoded'); headers.append('Autorisation', 'Basic' + btoa(login.Username + ':' + login.Password)); return this.http.post(this.apiBaseUrl + '/Account/Login', "grant_type=client_credentials", { headers: headers }) .map(réponse => { //code }); }</pré> <p> <pre class="brush:php;toolbar:false;">{ "error": "invalid_client", "error_description": "Les informations d'identification du client n'ont pas été trouvées dans les en-têtes ou le corps" }</pre> <p>我尝试将 origine 设置为 '<code>*</code>' 但它仍然以同样的方式失败。</p> <p><strong><em>编辑</em></strong> 只是根据以下信息进行更新。更改标头中的大小写没有任何效果,并且从 if 语句中提取代码也没有任何效果。</p> <p>将其放入每个 if 语句中。</p> <p><strong><em>编辑镜头 2</em></strong> 我确实需要一些帮助,如果有人有任何想法,我将非常感激。</p> <p><strong><em>Modifier la prise de vue 3</em></strong> 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. </p> <p><code>{"error": "invalid_client", "error_description": "Identifiants du client introuvables dans l'en-tête ou le corps"}</code></p> <p>Mes en-têtes de réponse ressemblent à ceci</p> <pre class="brush:php;toolbar:false;">Access-Control-Allow-Credentials:true Access-Control-Allow-Headers : autorisation, type de contenu, acceptation, origine Méthodes d'autorisation de contrôle d'accès : GET, POST, OPTIONS Contrôle d'accès-Autoriser-Origine :*</pre> <p>Une fois que cela fonctionnera, je le remplacerai de * par uniquement mon domaine. Mais maintenant je le laisse comme *. </p> <p><strong>Mon en-tête sur demande. </strong></p>
P粉642920522
P粉642920522

répondre à tous(2)
P粉502608799

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 :

header("Access-Control-Allow-Origin: http://localhost:4200");   
header("Content-Type: application/json; charset=UTF-8");    
header("Access-Control-Allow-Methods: POST, DELETE, OPTIONS");    
header("Access-Control-Max-Age: 3600");    
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");

Après eux, je peux ignorer les demandes d'options :

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {    
   return 0;    
}

Cette approche m'a aidé à gérer les méthodes de requête intégrées « publier » et « supprimer » dans Angular.

P粉316890884

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 :

//The Response object
    $res = $app->response;

    $res->headers->set('Content-Type', 'application/json');
    $res->headers->set('Access-Control-Allow-Origin', 'http://example.com');
    $res->headers->set('Access-Control-Allow-Credentials', 'true');
    $res->headers->set('Access-Control-Max-Age', '60');
    $res->headers->set('Access-Control-Allow-Headers', 'AccountKey,x-requested-with, Content-Type, origin, authorization, accept, client-security-token, host, date, cookie, cookie2');
    $res->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');

    if ( ! $req->isOptions()) {
        // this continues the normal flow of the app, and will return the proper body
        $this->next->call();
    } else {
        //stops the app, and sends the response
        return $res;
    }

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

  • Si vous utilisez "Authorization: Bearer", alors "Access-Control-Allow-Headers" doit également contenir "Authorization", sinon la demande échouera
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal