Nagłówki żądań między źródłami (CORS) z nagłówkami PHP


146

Mam prosty skrypt PHP, który próbuję wykonać międzydomenowe żądanie CORS:

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

Jednak nadal otrzymuję błąd:

Pole nagłówka żądania X-Requested-Withnie jest dozwolone przezAccess-Control-Allow-Headers

Coś mi brakuje?

Odpowiedzi:


59

Access-Control-Allow-Headersnie pozwala *na akceptowaną wartość, zobacz Dokumentację Mozilli tutaj .

Zamiast gwiazdki należy wysłać zaakceptowane nagłówki (najpierw X-Requested-Withzgodnie z błędem).


289

Prawidłowa obsługa żądań CORS jest nieco bardziej skomplikowana. Oto funkcja, która będzie reagować pełniej (i prawidłowo).

/**
 *  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
Zwróć uwagę, że wysłanie wartości HTTP Origin z powrotem jako dozwolonego źródła pozwoli każdemu na wysyłanie do Ciebie żądań z plikami cookie, a tym samym potencjalnie kradzież sesji użytkownika, który zalogował się w Twojej witrynie, a następnie wyświetlił stronę atakującego. Chcesz wysłać znak „*” (co uniemożliwi korzystanie z plików cookie, zapobiegając kradzieży sesji) lub określone domeny, dla których witryna ma działać.
— Jules,

1
Zgoda. W praktyce prawdopodobnie nie pozwoliłbyś żadnej starej domenie na korzystanie z usługi CORS, ograniczyłbyś ją do jakiegoś zestawu, któremu zdecydowałeś się zaufać.
— slashingweapon

FYI, to rozwiązanie działało tylko dla mnie Linux server, IISz jakiegoś powodu po prostu nie działało, nie wiem, czy to mój hosting, czy po prostu nie jest odpowiedniIIS
— ncubica

1
Dziękuję Ci! Muszę dodać tę odpowiedź do zakładek. Szkoda, że ​​nie możemy oznaczyć tego jako nowej odpowiedzi
— Ascherer

1
Jedyne, co naprawdę działa! .. Po prostu zmień Access-Control-Allow-Origin: * TO Access-Control-Allow-Origin: {$ _SERVER ['HTTP_ORIGIN']}
— Renan Franca

60

Otrzymałem ten sam błąd i naprawiłem go za pomocą następującego kodu PHP w moim skrypcie zaplecza:

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

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

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

35

Wiele opisów w całym Internecie nie wspomina, że ​​określenie Access-Control-Allow-Originnie wystarczy. Oto kompletny przykład, który działa dla mnie:

<?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
Proszę wyjaśnić, dlaczego nie wystarczy i co minimalna przykładem jest mało.
— halfpastfour.am

Niestety nie pamiętam dokładnie i nie mam teraz czasu, aby to ponownie zbadać, ale o ile pamiętam, były pewne podstawowe założenia po stronie serwera / przeglądarki, które sprawiły, że nie działała. To był minimalny kod, który działał dla mnie.
— Csongor Halmai

24

Po prostu udało mi się uzyskać dropzone i inną wtyczkę do pracy z tą poprawką (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');

dodaj to do swojego upload.php lub tam, gdzie chciałbyś wysłać swoje żądanie (na przykład, jeśli masz upload.html i musisz załączyć pliki do upload.php, a następnie skopiuj i wklej te 4 wiersze). Również jeśli używasz wtyczek / dodatków CORS w chrome / mozilla, pamiętaj, aby przełączać je więcej niż jeden raz, aby CORS był włączony


15

Jeśli chcesz stworzyć usługę CORS z PHP, możesz użyć tego kodu jako pierwszego kroku w pliku, który obsługuje żądania:

// 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 może stać się bólem głowy, jeśli nie zrozumiemy poprawnie jego działania. Używam ich w PHP i działają bez problemów. odniesienie tutaj

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

Tyle kodu działa dla mnie, gdy używam angular 4 jako strony klienta i PHP jako strony serwera.

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

3

to powinno działać

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

0

dodaj ten kod w .htaccess

dodaj w nagłówku niestandardowy klucz uwierzytelniania, taki jak 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

W systemie Windows wklej to polecenie w oknie uruchamiania , aby przetestować kod

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


Wyłączenie zabezpieczeń internetowych przeglądarki, nawet tymczasowe, to straszny pomysł
— Machavity
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.