#php #jquery #ajax #codeigniter
#php #javascript #xmlhttprequest #cors
Вопрос:
У меня есть простой PHP-скрипт, который я пытаюсь выполнить междоменный CORS-запрос:
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: *");
...
Тем не менее, я все еще получаю ошибку:
Поле заголовка запроса
X-Requested-With
не разрешеноAccess-Control-Allow-Headers
Что-нибудь, что я упускаю?
Комментарии:
1. 2022 и верхний ответ действительно работает (на некоторых версиях PHP), приятно.
Ответ №1:
Правильная обработка запросов 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
* - https://fetch.spec.whatwg.org/#http-cors-protocol
*
*/
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!";
}
Примечания по безопасности
Сверьте заголовок HTTP_ORIGIN со списком утвержденных источников.
Если источник не утвержден, вам следует отклонить запрос.
Пожалуйста, прочитайте спецификацию.
TL; DR
Когда браузер хочет выполнить межсайтовый запрос, он сначала подтверждает, что это нормально с «предварительным» запросом на URL. Разрешая CORS, вы сообщаете браузеру, что ответы с этого URL-адреса могут быть переданы другим доменам.
CORS не защищает ваш сервер. CORS пытается защитить ваших пользователей, сообщая браузерам, какие ограничения должны быть на обмен ответами с другими доменами. Обычно такой обмен категорически запрещен, поэтому CORS — это способ проделать дыру в обычной политике безопасности браузера. Эти отверстия должны быть как можно меньше, поэтому всегда проверяйте HTTP_ORIGIN на соответствие какому-либо внутреннему списку.
Здесь есть некоторые опасности, особенно если данные, которые предоставляет URL, обычно защищены. Вы фактически разрешаете содержимому браузера, созданному на каком-либо другом сервере, считывать (и, возможно, манипулировать) данными на вашем сервере.
Если вы собираетесь использовать CORS, пожалуйста, внимательно прочитайте протокол (он довольно маленький) и попытайтесь понять, что вы делаете. Для этой цели в примере кода указан ссылочный URL-адрес.
Безопасность заголовков
Было замечено, что заголовок HTTP_ORIGIN небезопасен, и это правда. Фактически, все HTTP-заголовки небезопасны для различных значений термина. Если заголовок не содержит проверяемой подписи / hmac или весь диалог не аутентифицируется через TLS, заголовки — это просто «то, что мне сказал браузер».
В этом случае браузер сообщает: «объект из домена X хочет получить ответ с этого URL. Это нормально? » Смысл CORS в том, чтобы иметь возможность ответить: «Да, я разрешаю это».
Комментарии:
1. Обратите внимание, что отправка исходного значения HTTP в качестве разрешенного источника позволит любому отправлять вам запросы с помощью файлов cookie, что потенциально может привести к краже сеанса у пользователя, который вошел на ваш сайт, а затем просмотрел страницу злоумышленника. Вы либо хотите отправить ‘*’ (который запретит использование файлов cookie, тем самым предотвратив кражу сеанса), либо конкретные домены, для которых вы хотите, чтобы сайт работал.
2. Согласен. На практике вы, вероятно, не разрешили бы какому-либо старому домену использовать ваш сервис CORS, вы бы ограничили его некоторым набором, которому вы решили доверять.
3. Единственное, что действительно работает !.. Просто измените Access-Control-Allow-Origin: * НА Access-Control-Allow-Origin: {$_SERVER[‘HTTP_ORIGIN’]}
4. Безоговорочно разрешая использование любого источника
ACAC: true
, вы, по сути, выбрасываете Политику одного и того же источника в окно. Этот ответ — ужасный совет с точки зрения безопасности, и он должен быть предан забвению.5. За использование проголосовали
$_SERVER['HTTP_ORIGIN']
против . Это огромный риск для безопасности.
Ответ №2:
Я получил ту же ошибку и исправил ее с помощью следующего PHP в моем серверном скрипте:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
header("Access-Control-Allow-Headers: X-Requested-With");
Комментарии:
1. должны ли эти три строки добавляться в начало файла PHP? Например, <?php header(‘Access-Control-Allow-Origin: *’); header(‘Access-Control-Allow-Methods: GET, POST’); header(«Access-Control-Allow-Headers: X-Requested-With»);
Ответ №3:
Access-Control-Allow-Headers
не допускается *
в качестве принятого значения, см. Документацию Mozilla здесь .
Вместо звездочки вы должны отправить принятые заголовки (сначала X-Requested-With
, как указано в ошибке).
Обновить:
*
теперь принято есть Access-Control-Allow-Headers
.
Согласно MDN Web Docs 2021:
Значение
*
учитывается только как специальное подстановочное значение для запросов без учетных данных (запросов без HTTP-файлов cookie или информации об аутентификации HTTP). В запросах с учетными данными оно обрабатывается как буквальное имя заголовка*
без специальной семантики. Обратите внимание, что заголовок авторизации не может быть подстановочным и всегда должен быть указан явно.
Комментарии:
1. По состоянию на 2021 год, похоже
*
, что теперь это принято в соответствии с документами MDN.
Ответ №4:
Во многих описаниях, размещенных в Интернете, не упоминается, что указания 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. Пожалуйста, объясните, почему этого недостаточно и какого минимального примера достаточно.
2. К сожалению, я точно не помню, и сейчас у меня нет времени исследовать это снова, но, насколько я помню, были некоторые основные предположения со стороны веб-сервера / браузера, из-за которых он не работал. Это был минимальный код, который работал для меня.
3. если уже отправлено в виртуальный хост apache .. тогда работает только этот код ..if ($_SERVER[‘REQUEST_METHOD’] === ‘OPTIONS’) {die(); }
4. По сути, здесь говорится, что этого достаточно, только не в том случае, если метод запроса — «параметры».
Ответ №5:
Мне просто удалось заставить dropzone и другой плагин работать с этим исправлением (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');
добавьте это в свой upload.php или куда вы могли бы отправить свой запрос (например, если у вас есть upload.html и вам нужно прикрепить файлы к upload.php , затем скопируйте и вставьте эти 4 строки).
Кроме того, если вы используете плагины / дополнения CORS в Chrome / Mozilla, обязательно переключайте их более одного раза, чтобы CORS был включен
Комментарии:
1. нужно ли нам разрешать исходный заголовок? звучит странно
Ответ №6:
Если вы хотите создать службу 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
Комментарии:
1. Это решает мою проблему — по-видимому, мой веб-сервис PHP не может правильно обработать запрос ПАРАМЕТРОВ, на который полагается мой интерфейс Angular перед отправкой запроса POST. Спасибо!
Ответ №7:
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");
Комментарии:
1. Я использовал это в Codeigniter 4.1.3, и это работает
Ответ №8:
Этот большой объем кода работает для меня при использовании angular 4 в качестве клиентской части и PHP в качестве серверной.
header("Access-Control-Allow-Origin: *");
Комментарии:
1. Будьте осторожны при использовании подстановочного знака «*». Никогда не открывайте его, если это не то, что вы действительно собираетесь сделать. Что касается тестирования вашего приложения angular, укажите localhost: 4200 , и оно будет работать, оставаясь при этом более безопасным.
2. Протестировано на сервере LAMP под управлением PHP 7.4.x
Ответ №9:
это должно сработать
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Cache-Control, Pragma, Authorization, Accept, Accept-Encoding");
Комментарии:
1. Это очень хорошо работало на VUE XAMPP (PHP)
Ответ №10:
добавьте этот код в .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"
Ответ №11:
Я использовал эти 5 заголовков и после этого решил ошибку cors (серверная часть: PHP, интерфейс: VUE JS)
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS, post, get');
header("Access-Control-Max-Age", "3600");
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');
header("Access-Control-Allow-Credentials", "true");