Поточні запити заголовків (CORS) із заголовками PHP


146

У мене є простий скрипт PHP, який я намагаюсь виконати міждоменний запит CORS:

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

І все-таки я отримую помилку:

Поле заголовка запиту X-Requested-WithзабороненоAccess-Control-Allow-Headers

Щось мені не вистачає?

Відповіді:


59

Access-Control-Allow-Headersне дозволяє *прийняти значення, див . тут Документацію на Mozilla .

Замість зірочки слід надіслати прийняті заголовки (спочатку, X-Requested-Withяк говорить помилка).


289

Правильне поводження із запитами CORS - це значно більше. Ось функція, яка відповість більш повно (і правильно).

/**
 *  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
Зауважте, що повернення значення HTTP Origin назад як дозволене походження дозволить кожному надсилати вам запити за допомогою cookie-файлів, таким чином, потенційно може вкрасти сеанс у користувача, який увійшов на ваш сайт, а потім переглянув сторінку зловмисника. Ви або хочете надіслати "*" (що забороняє cookie, тим самим запобігаючи крадіжку сеансу) або конкретні домени, для яких ви хочете, щоб сайт працював.
Jules

1
Домовились. На практиці ви, ймовірно, не дозволили б будь-якому старому домену скористатись вашою послугою CORS, ви обмежили його набором, якому ви вирішили довіряти.
рубаючий

FYI, це рішення працювало на мене тільки в Linux server, IISтому що чомусь просто не вийшло, я не знаю, чи є його хостинг чи просто він не підходить дляIIS
ncubica

1
Дякую! Додайте закладку до цієї відповіді. Шкода, що ми не можемо позначити це новою відповіддю
Ascherer,

1
Єдине, що справді працює! .. Просто змініть Access-Control-Allow-Origin: * TO Access-Control-Allow-Origin: {$ _SERVER ['HTTP_ORIGIN']}
Ренан Франка,

60

Я отримав таку ж помилку, і виправив її за допомогою наступного PHP у своєму бек-енд-скрипті:

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

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

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

35

Багато описів в Інтернеті не згадують, що уточнення Access-Control-Allow-Originнедостатньо. Ось повний приклад, який працює для мене:

<?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
Будь ласка , поясніть , чому це не досить , і то , що мінімальний приклад є досить.
halfpastfour.am

На жаль, я точно не пам’ятаю, і в мене зараз немає часу досліджувати його знову, але, наскільки я пам’ятаю, були деякі основні припущення з боку веб-сервера / браузера, які змусили його не працювати. Це був мінімальний код, який працював на мене.
Csongor Halmai

24

Мені просто вдалося отримати dropzone та інший плагін для роботи з цим виправленням (angularjs + php backkend)

 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');

додайте це у файл upload.php або там, де ви б надіслали запит (наприклад, якщо у вас є файл upload.html і вам потрібно приєднати файли до upload.php, потім скопіюйте та вставте ці 4 рядки). Крім того, якщо ви використовуєте плагіни / аддони CORS в хромі / мозіла, не забудьте перемикати їх не один раз, щоб активізувати CORS


15

Якщо ви хочете створити послугу CORS з PHP, ви можете використовувати цей код як перший крок у вашому файлі, який обробляє запити:

// 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 може стати головним болем, якщо ми не правильно зрозуміємо його функціонування. Я використовую їх у PHP, і вони працюють без проблем. посилання тут

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

Цей великий код працює для мене під час використання кутового 4 в якості клієнтської та PHP в якості серверного.

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

3

це має працювати

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

0

додайте цей код у .htaccess

додайте спеціальні ключі для автентифікації у заголовку, наприклад 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

У Windows вставте цю команду у вікно запуску лише на час, щоб перевірити код

chrome.exe --user-data-dir = "C: / Chrome dev session" - відключити веб-безпеку


Відключення веб-безпеки вашого веб-переглядача, навіть тимчасово, є жахливою ідеєю
Machavity
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.