Заголовки CORS изменяются в браузере, в результате чего контент блокируется - PullRequest
10 голосов
/ 07 марта 2019

Обновление 2 (полный набор журналов)

С точки зрения клиента

Заголовки запроса:

POST /dev/micro_server.php HTTP / 1.1 Ведущий: production-server.com
Подключение: keep-alive
Длина контента: 86
Прагма: без кеша
Cache-Control: без кеша
Принять: text / html, / ; д = 0,01
Происхождение: https://debug.dev
Пользователь-агент: Mozilla / 5.0 (X11; Linux x86_64) AppleWebKit / 537.36 (KHTML, как Gecko) Chrome / 71.0.3578.98 Safari / 537,36 OPR / 58,0,31,30,90
Тип контента: application / x-www-form-urlencoded; кодировка = UTF-8 * * тысяча двадцать-одина Рефере: https://debug.dev/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US, en; q = 0,9
Cookie: debugger_session = iq4tbdk374mtvodsd3edcf2jq5

Заголовки ответа:

HTTP / 1.1 200 OK
Сервер: nginx / 1.4.6 (Ubuntu)
Дата: вторник, 12 марта 2019 г. 12:01:27 GMT
Тип контента: текст / html
Передача-кодировка: чанки
Подключение: keep-alive
X-Powered-By: PHP / 5.5.9-1ubuntu4.17
Методы контроля доступа-разрешения: GET, POST, OPTIONS
Контроль доступа-Разрешить происхождение: https://production -server.com
Access-Control-Allow-Credentials: true
Срок действия истекает в четверг, 19 ноября 1981 г. Cache-Control: без сохранения, без кэширования, обязательная повторная проверка, пост-проверка = 0, предварительная проверка = 0
Прагма: без кеша
Контент-кодировка: gzip

Ошибка консоли:

Доступ к XMLHttpRequest по адресу 'https://production -server.com / dev / micro_server.php ' from origin 'https://debug.dev' заблокирован политикой CORS: «Access-Control- Заголовок Allow-Origin 'имеет значение' https://production -server.com ', которое не равно указанному источнику.

Предупреждение консоли:

Блокировка перекрестного чтения (CORB) заблокировала ответ перекрестного происхождения https://daikai.no/dev/micro_server.php с MIME-типом text / html. Подробнее см. https://www.chromestatus.com/feature/5629709824032768.

С точки зрения сервера

Это то, что сервер говорит, что получил и отправил (проверьте код, который выполняет регистрацию в обновлении 1):

Array
(
    [req] => Array
        (
            ...
            [HTTP_ORIGIN] => https://debug.dev
            ...
        )

    [rsp] => Array
        (
            [0] => X-Powered-By: PHP/5.5.9-1ubuntu4.17
            [1] => Access-Control-Allow-Origin: https://debug.dev
            [2] => Access-Control-Allow-Methods: GET, POST, OPTIONS
            [3] => Access-Control-Allow-Credentials: true
        )

)

Обновление

Я добавил некоторую регистрацию на сервере, и скрипт теперь начинается со следующих строк:

# allow access from other domains
    header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
    header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
    header("Access-Control-Allow-Credentials: true");

$all = [
    'req' => $_SERVER,
    'rsp' => headers_list()
];

$s = print_r($all, true);
$p = '/var/www/path/to/file_' . uniqid() . '.txt';
file_put_contents($p, $s);

Этим я могу подтвердить, что запрос поступает на сервер с правильным источником, и сервер отправляет обратно правильные заголовки CORS. Тем не менее, Access-Control-Allow-Origin в консоли разработчика неверен, и запрос заблокирован.

Вот урезанный журнал, полученный с кодом выше:

Array
(
    [req] => Array
        (
            ...
            [HTTP_ORIGIN] => https://debug.dev
            ...
        )

    [rsp] => Array
        (
            [0] => X-Powered-By: PHP/5.5.9-1ubuntu4.17
            [1] => Access-Control-Allow-Origin: https://debug.dev
            [2] => Access-Control-Allow-Methods: GET, POST, OPTIONS
            [3] => Access-Control-Allow-Credentials: true
        )

)

Вопрос

Как и почему Access-Control-Allow-Origin изменяется на https://production.com, когда фактический полученный заголовок равен Access-Control-Allow-Origin: https://debug.dev?


(Исходное сообщение)

Фон

У меня есть веб-инструмент отладки, который я установил на свой локальный компьютер для разработки. С записью в моем / etc / hosts я назначил ей домен debug.dev. Я также добавил полномочия локального ЦС и успешно создал сертификат SSL для доменного имени, так что теперь я могу открыть https://debug.dev/ в своем браузере, и инструмент отладки открывается нормально.

Этот инструмент предназначен для работы с промежуточными и рабочими серверами. Поэтому он должен отправлять запросы AJAX в другие домены. У меня есть полный контроль над этими серверами, и я отправляю заголовки CORS с этих серверов следующим образом:

header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
header("Access-Control-Allow-Credentials: true");

Выпуск

Теперь я сталкиваюсь с непонятной ситуацией, когда при отправке запроса AJAX на рабочий сервер я получаю обратно Неправильные CORS-заголовки с доменом СЕРВЕРА, например:

Access-Control-Allow-Credentials: true
Контроль доступа-Разрешить происхождение: https://production -server.com

Но если я щелкну правой кнопкой мыши и использую Открыть в новой вкладке , то заголовки CORS будут такими, какими они должны быть; т.е.

Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://debug.dev

Насколько я могу видеть, единственные различия между запросами состоят в том, что первый из них отправляется как запрос AJAX POST и, следовательно, отправляет заголовок HTTP_X_REQUESTED_WITH.тогда как второй запрос отправляется как обычный запрос GET.Как это может привести к тому, что сервер вернет другой заголовок CORS?

Ответы [ 2 ]

3 голосов
/ 13 марта 2019

Проблема может быть похожа на мой ответ здесь :

Сервер не настроен для ответа на запросы OPTIONS с правильными заголовками «Access-Control-Allow-».

Открытие URL-адреса в новой вкладке является запросом GET и работает, поскольку не выполняет предварительный запрос поскольку он удовлетворяет критериям простого простого запроса , определенного в документации CORS

С другой стороны, запрос ajax запрос POST и соответствует критериям: запрос Preflighted , что означает, что запрос preflight OPTIONS должен быть сделан первым .

Короче говоря,вы правильно настроили заголовки ответов CORS, но сервер не настроен на добавление этих заголовков для запросов метода OPTIONS .

Решение заключается в обработке OPTIONS запросов к коду сервера с ответом 2xx и добавлении ** Access-Control-Allow- как вы делаете для запросов GET и POST.Помните, что запросы OPTIONS не включают никаких параметров, поэтому это следует делать перед любой проверкой или анализом запроса.

Более того, согласно Access-Control-Allow-Origin документация :

Если сервер указывает один источник, а не подстановочный знак "*", то сервер должен также включить источник в заголовок ответа Vary - чтобы указать клиентам, что ответы сервера будут отличаться в зависимости от значениязаголовок запроса источника.

Поэтому задайте также заголовок ответа Vary :

Например, в верхней части сценария попробуйте:

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
    header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
    header("Access-Control-Allow-Credentials: true");
    header("Vary: Origin");
    exit;
}

Ссылки

Предварительно просвеченные запросы

Ответ на предпечатную проверку 403 запрещен

1 голос
/ 12 марта 2019

Проблема в том, что вы используете header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']); (кстати, не очень рекомендуется), и вы получаете неправильный заголовок. Бьюсь об заклад по одной из причин:

  • Веб-сервер перезаписывает заголовки.
  • Браузер использует кеш, хотя не должен. (BFC).
  • Вы не загрузили обновленный код на запрашивающий сервер.

Начнем с конца.

  • Не верь себе, проверь. (Я не раз смотрел, мы не работали, а потом пришло отражение, что я не загружаю изменения :)).
  • Отключить кеш в отладчике браузера. (у вас должен быть открытый отладчик) Если это проблема, и функция должна быть доступна в пуле, добавьте метку времени к запросу.
  • Проверка конфигурации nginx / apache / панель сервера

Знаете ли вы, что используемая вами конструкция является синонимом Access-Control-Allow-Origin: *? Вам следует проверить HTTP_ORIGIN, принадлежит ли он разрешенному пулу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...