Intestazioni richieste di origine incrociata (CORS) con intestazioni PHP


146

Ho un semplice script PHP che sto tentando una richiesta CORS tra domini:

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

Eppure ho ancora l'errore:

Il campo dell'intestazione della richiesta X-Requested-Withnon è consentito daAccess-Control-Allow-Headers

Qualcosa che mi manca?

Risposte:


59

Access-Control-Allow-Headersnon consente *come valore accettato, consultare la documentazione di Mozilla qui .

Invece dell'asterisco, è necessario inviare le intestazioni accettate (prima X-Requested-Withcome dice l'errore).


289

La gestione corretta delle richieste CORS è un po 'più complicata. Ecco una funzione che risponderà in modo più completo (e corretto).

/**
 *  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
Tieni presente che l'invio del valore dell'origine HTTP come origine consentita consentirà a chiunque di inviarti richieste con i cookie, potenzialmente rubando una sessione da un utente che ha effettuato l'accesso al tuo sito e visualizzato la pagina di un utente malintenzionato. O vuoi inviare '*' (che disabiliterà i cookie impedendo così il furto di sessioni) o i domini specifici per i quali vuoi che il sito funzioni.
Jules,

1
Concordato. In pratica, probabilmente non permetteresti a qualsiasi vecchio dominio di utilizzare il tuo servizio CORS, lo limiteresti a un set di cui hai deciso di fidarti.
slashingweapon,

Cordiali saluti, questa soluzione ha funzionato solo per me in Linux server, IISper qualche motivo non ha funzionato, non so se è il mio hosting o semplicemente non è adattoIIS
ncubica,

1
Grazie! Devi aggiungere questa risposta ai segnalibri. Peccato che non possiamo contrassegnarlo come una nuova risposta
Ascherer,

1
L'unico che funziona davvero! .. Cambia solo Access-Control-Allow-Origin: * TO Access-Control-Allow-Origin: {$ _SERVER ['HTTP_ORIGIN']}
Renan Franca,

60

Ho avuto lo stesso errore e l'ho risolto con il seguente PHP nel mio script back-end:

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

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

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

35

Molte descrizioni su Internet non menzionano che specificare Access-Control-Allow-Originnon sia sufficiente. Ecco un esempio completo che funziona per me:

<?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
Spiega perché non è abbastanza e quale esempio minimo è sufficiente.
halfpastfour.am,

Sfortunatamente, non ricordo esattamente e non ho tempo per indagare di nuovo, ma, per quanto mi ricordi, c'erano alcuni presupposti di base dal lato server / browser che lo hanno reso non funzionante. Questo era il codice minimo che ha funzionato per me.
Csongor Halmai,

24

Sono semplicemente riuscito a far funzionare Dropzone e altri plugin con questa correzione (angularjs + back-end 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');

aggiungilo nel tuo upload.php o dove invierai la tua richiesta (ad esempio se hai upload.html e devi allegare i file a upload.php, quindi copia e incolla queste 4 righe). Inoltre, se utilizzi plug-in / addon CORS in chrome / mozilla, assicurati di attivarli più di una volta, per abilitare CORS


15

Se vuoi creare un servizio CORS da PHP, puoi usare questo codice come primo passo nel tuo file che gestisce le richieste:

// 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 può diventare un mal di testa, se non capiamo correttamente il suo funzionamento. Li uso in PHP e funzionano senza problemi. riferimento qui

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

Questo codice funziona per me quando uso angular 4 come lato client e PHP come lato server.

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

3

questo dovrebbe funzionare

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

0

aggiungi questo codice in .htaccess

aggiungi la chiave di autenticazione personalizzata nell'intestazione come 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

In Windows, incolla questo comando nella finestra di esecuzione solo per ora per testare il codice

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


Disabilitare la sicurezza del tuo browser, anche temporaneamente, è un'idea terribile
Machavity
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.