Maison  >  Questions et réponses  >  le corps du texte

Problème CORS en PHP : la réponse de la demande de contrôle en amont n'est pas transmise. sources autorisées

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.

P粉564192131P粉564192131385 Il y a quelques jours668

répondre à tous(2)je répondrai

  • P粉952365143

    P粉9523651432023-10-22 00:47:32

    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.

    répondre
    0
  • P粉860370921

    P粉8603709212023-10-22 00:29:25

    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

    répondre
    0
  • Annulerrépondre