En-têtes de requête Cross-Origin (CORS) avec en-têtes PHP


146

J'ai un script PHP simple que j'essaye une requête CORS inter-domaines:

<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: *");
...

Pourtant, j'obtiens toujours l'erreur:

Le champ d'en-tête de la demande X-Requested-Withn'est pas autorisé parAccess-Control-Allow-Headers

Quelque chose me manque?

Réponses:


59

Access-Control-Allow-Headersn'autorise pas *comme valeur acceptée, consultez la documentation de Mozilla ici .

Au lieu de l'astérisque, vous devez envoyer les en-têtes acceptés (d'abord X-Requested-Withcomme le dit l'erreur).


289

La gestion correcte des requêtes CORS est un peu plus complexe. Voici une fonction qui répondra plus complètement (et correctement).

/**
 *  An example CORS-compliant method.  It will allow any GET, POST, or OPTIONS requests from any
 *  origin.
 *
 *  In a production environment, you probably want to be more restrictive, but this gives you
 *  the general idea of what is involved.  For the nitty-gritty low-down, read:
 *
 *  - https://developer.mozilla.org/en/HTTP_access_control
 *  - http://www.w3.org/TR/cors/
 *
 */
function cors() {

    // Allow from any origin
    if (isset($_SERVER['HTTP_ORIGIN'])) {
        // Decide if the origin in $_SERVER['HTTP_ORIGIN'] is one
        // you want to allow, and if so:
        header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
        header('Access-Control-Allow-Credentials: true');
        header('Access-Control-Max-Age: 86400');    // cache for 1 day
    }

    // Access-Control headers are received during OPTIONS requests
    if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {

        if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
            // may also be using PUT, PATCH, HEAD etc
            header("Access-Control-Allow-Methods: GET, POST, OPTIONS");         

        if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
            header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");

        exit(0);
    }

    echo "You have CORS!";
}

32
Notez que le renvoi de la valeur HTTP Origin comme origine autorisée permettra à quiconque de vous envoyer des demandes avec des cookies, volant ainsi potentiellement une session d'un utilisateur qui s'est connecté à votre site puis a consulté la page d'un attaquant. Vous souhaitez soit envoyer '*' (ce qui interdira les cookies empêchant ainsi le vol de session) ou les domaines spécifiques pour lesquels vous souhaitez que le site fonctionne.
Jules

1
D'accord. En pratique, vous n'autoriseriez probablement pas n'importe quel ancien domaine à utiliser votre service CORS, vous le limiteriez à un ensemble auquel vous avez décidé de faire confiance.
slashingweapon

Pour info, cette solution ne fonctionnait que pour moi dans un Linux server, IISpour une raison quelconque, ne fonctionnait tout simplement pas, je ne sais pas si c'est mon hébergement ou simplement si elle ne convient pasIIS
ncubica

1
Je vous remercie! Vous devez mettre cette réponse dans vos favoris. Dommage que nous ne puissions pas marquer cela comme une nouvelle réponse
Ascherer

1
Le seul qui fonctionne vraiment! .. Il suffit de changer Access-Control-Allow-Origin: * TO Access-Control-Allow-Origin: {$ _SERVER ['HTTP_ORIGIN']}
Renan Franca

60

J'ai eu la même erreur et je l'ai corrigée avec le PHP suivant dans mon script back-end:

header('Access-Control-Allow-Origin: *');

header('Access-Control-Allow-Methods: GET, POST');

header("Access-Control-Allow-Headers: X-Requested-With");

35

De nombreuses descriptions sur Internet ne mentionnent pas qu'il Access-Control-Allow-Originne suffit pas de spécifier . Voici un exemple complet qui fonctionne pour moi:

<?php
    if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Allow-Methods: POST, GET, DELETE, PUT, PATCH, OPTIONS');
        header('Access-Control-Allow-Headers: token, Content-Type');
        header('Access-Control-Max-Age: 1728000');
        header('Content-Length: 0');
        header('Content-Type: text/plain');
        die();
    }

    header('Access-Control-Allow-Origin: *');
    header('Content-Type: application/json');

    $ret = [
        'result' => 'OK',
    ];
    print json_encode($ret);

1
S'il vous plaît expliquer pourquoi il ne suffit pas et quel exemple minimal est suffisant.
halfpastfour.am

Malheureusement, je ne me souviens pas exactement et je n'ai pas le temps maintenant d'enquêter à nouveau mais, autant que je me souvienne, il y avait des hypothèses de base du côté du serveur Web / du navigateur qui l'empêchaient de fonctionner. C'était le code minimal qui fonctionnait pour moi.
Csongor Halmai

24

J'ai simplement réussi à faire fonctionner dropzone et d'autres plugins avec ce correctif (backend angularjs + php)

 header('Access-Control-Allow-Origin: *'); 
    header("Access-Control-Allow-Credentials: true");
    header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
    header('Access-Control-Max-Age: 1000');
    header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token , Authorization');

ajoutez-le dans votre upload.php ou là où vous enverriez votre demande (par exemple si vous avez upload.html et que vous devez joindre les fichiers à upload.php, puis copiez et collez ces 4 lignes). De plus, si vous utilisez des plugins / addons CORS dans chrome / mozilla, assurez-vous de les basculer plusieurs fois, afin que CORS soit activé.


15

Si vous souhaitez créer un service CORS à partir de PHP, vous pouvez utiliser ce code comme première étape de votre fichier qui gère les requêtes:

// Allow from any origin
if(isset($_SERVER["HTTP_ORIGIN"]))
{
    // You can decide if the origin in $_SERVER['HTTP_ORIGIN'] is something you want to allow, or as we do here, just allow all
    header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
}
else
{
    //No HTTP_ORIGIN set, so we allow any. You can disallow if needed here
    header("Access-Control-Allow-Origin: *");
}

header("Access-Control-Allow-Credentials: true");
header("Access-Control-Max-Age: 600");    // cache for 10 minutes

if($_SERVER["REQUEST_METHOD"] == "OPTIONS")
{
    if (isset($_SERVER["HTTP_ACCESS_CONTROL_REQUEST_METHOD"]))
        header("Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT"); //Make sure you remove those you do not want to support

    if (isset($_SERVER["HTTP_ACCESS_CONTROL_REQUEST_HEADERS"]))
        header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");

    //Just exit with 200 OK with the above headers for OPTIONS method
    exit(0);
}
//From here, handle the request as it is ok

8

CORS peut devenir un casse-tête, si nous ne comprenons pas correctement son fonctionnement. Je les utilise en PHP et ils fonctionnent sans problème. référence ici

header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Max-Age: 1000");
header("Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Cache-Control, Pragma, Authorization, Accept, Accept-Encoding");
header("Access-Control-Allow-Methods: PUT, POST, GET, OPTIONS, DELETE");

7

Ce code fonctionne pour moi lorsque j'utilise angular 4 comme côté client et PHP comme côté serveur.

header("Access-Control-Allow-Origin: *");

3

cela devrait fonctionner

header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Cache-Control, Pragma, Authorization, Accept, Accept-Encoding");

0

ajoutez ce code dans .htaccess

ajouter des clés d'authentification personnalisées dans l'en-tête comme app_key, auth_key..etc

Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers: "customKey1,customKey2, headers, Origin, X-Requested-With, Content-Type, Accept, Authorization"

-1

Sous Windows, collez cette commande dans la fenêtre d' exécution juste le temps de tester le code

chrome.exe --user-data-dir = "C: / Chrome dev session" --disable-web-security


Désactiver la sécurité Web de votre navigateur, même temporairement, est une mauvaise idée
Machavity
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.