Несовместимые запросы опций предпечатной проверки AJAX

Я надеюсь, что этот вопрос не слишком расплывчат, но я чувствую, что упускаю что-то фундаментальное Вот ситуация, в которой я нахожусь. У нас есть толстое клиентское приложение, которое работает на локальном компьютере каждого пользователя (Windows 7) и предоставляет API-интерфейс JavaScript для взаимодействия с приложением. У нас есть веб-приложение, которое размещено на сервере, но делает запросы AJAX к локальному хосту для взаимодействия с JS API толстых клиентов.

На одной машине мы загружаем веб-приложение. Все AJAX-запросы к localhost выполняются без предварительных запросов OPTIONS. На вкладке net консоли JS отображаются выполняемые POST и ответы успешны (я получаю от толстого клиента информацию о том, какие заголовки следует включить в ответ, включая все необходимые заголовки CORS).

На другом компьютере мы загружаем веб-приложение с того же сервера. Однако, когда AJAX-запросы отправляются на localhost, выполняется (ожидаемый) запрос OPTIONS. К сожалению, толстый клиент не отвечает с соответствующим заголовком Access-Control-Allow-Origin, поэтому последующий POST не может быть выполнен.

Браузеры не имеют значения, мы протестировали последние версии Firefox и Chrome, и мы всегда получаем одинаковое поведение на машинах. Мы проверили на 4 машинах - 2 отправляют ВАРИАНТЫ, 2 просто отправляют ПОЧТУ без предшествующих ВАРИАНТОВ. Похоже, что от браузера зависит, отличается ли назначение AJAX от источника и отправляет ли он запрос предварительной проверки. Я не могу понять, почему моя машина не отправляет запросы OPTIONS, даже если запросы AJAX (либо localhost, либо lvh.me) являются хостом / доменом, отличным от источника веб-страницы. Тем не менее, загрузка той же страницы с другого компьютера производит их.

Есть ли какая-то настройка браузера, которая влияет на это? Или настройка Windows? Почему мы когда-либо видим другое поведение на этом?

Update1:

Чтобы упростить и уточнить, у меня есть две машины, machineA и machineB. Обе машины загружают веб-приложение с удаленного сервера, example.com. На обеих машинах установлено полнофункциональное толстое приложение, установленное на их локальных машинах, которое предоставляет веб-сервер и API. Веб-приложение, загружаемое с сайта example.com, содержит код JavaScript для отправки запросов AJAX на localhost, чтобы каждый пользователь мог взаимодействовать со своим собственным локальным экземпляром приложения толстого клиента. Поскольку localhost!= Example.com, запросы следует рассматривать как междоменные.

Когда machineA отправляет стандартный JQuery AJAX-запрос на localhost (из которых полезная нагрузка POST просто "true", что заставит толстый клиент выводить значение обратно - просто используется для опроса, чтобы определить, является ли толстый клиент четным доступно), POST выполняется напрямую без запроса OPTIONS: POST http://localhost:4000/cgi-bin/Extensions/GeoLinkConsole/evaljs.html 200 OK 0ms Интересно, что ответ от этого POST должен включать Access-Control- Allow-Origin заголовок с example.com во избежание ошибки CORS.

Когда machineB загружает ту же страницу с сайта example.com, отправляет тот же стандартный запрос jQuery AJAX на локальный хост с той же "истинной" полезной нагрузкой, браузер отправляет запрос OPTIONS. Такое поведение я бы на самом деле ожидал. Ответ на запрос OPTIONS с 200 OK, однако он не включает заголовок Access-Control-Allow-Origin, поэтому он предотвращает прохождение POST. Это не моя главная проблема и, очевидно, проблема с толстым клиентом. Мой самый большой вопрос - почему некоторые машины генерируют ОПЦИИ, а некоторые нет. Я надеюсь, что это помогает объяснить.

Обновление 2:

Я включаю оба набора заголовков запроса. Я не знал, что фактический заголовок запроса может повлиять на то, будет ли генерироваться запрос OPTIONS. Сразу же я вижу, что тот, который отправляет OPTIONS, включает в себя и Acces-Control-Request-Headers и Access-Control-Request_Method, который другой не делает...

Запросите заголовки с компьютера, который отправляет сообщение POST без опций:

Accept:    text/plain, */*; q=0.01
Accept-Encoding:    gzip, deflate
Accept-Language:    en-US,en;q=0.5
Content-Length:    354
Content-Type:   text/plain; charset=UTF-8
Host:    localhost:4000
Origin:    http://example.com:7802
Referer:    http://example.com:7802/
User-Agent:    Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0

Запросить заголовки с компьютера, который отправляет ОПЦИИ:

Accept:    */*
Accept-Encoding:    gzip, deflate, sdch
Accept-Language:    en-US,en;q=0.8
Access-Control-Request-Headers:    accept, content-type, x-csrftoken
Access-Control-Request-Method:    POST
Connection:    keep-alive
Host:    localhost:4000
Origin:    http://example.com:7802
Referer:    http://example.com:7802/
User-Agent:    Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36

Кроме того, на машине есть "общий" блок заголовков - я предполагаю, что заголовки запроса, которые я только что разместил, были для исходного запроса POST, и они относятся к предварительному запросу OPTIONS:

Request URL:    http://localhost:4000/cgi-bin/Extensions/GeoLinkConsole/evaljs.html
Request Method:   OPTIONS
Status Code:    200 OK
Remote Address:    127.0.0.1:4000

1 ответ

Решение

(Возможно, вас заинтересует прочтение "непростых" зелий моего ответа на тему " Как работает заголовок Access-Control-Allow-Origin"? HTML5-записи на CORS, чтобы узнать, в общем, почему выполняются предварительные запросы OPTIONS.)

Как видите, запрос OPTIONS включает Access-Control-Request-Headers который включает в себя имя заголовка x-csrftoken, Это означает, что JavaScript пытается отправить заголовок x-csrftoken, Так как это не простой заголовок CORS (т.е. Accept, Accept-Language, Content-Language, и иногда Content-Type), это должно быть сначала разрешено предварительным запросом OPTIONS.

В дополнение к нормальному Access-Control-Allow-Origin заголовок, сервер должен ответить на предварительный просмотр OPTIONS с помощью Access-Control-Allow-Headers заголовок, который включает в себя x-csrftoken Название заголовка. Как только это будет сделано, браузер разрешит фактический запрос POST пройти на сервер.

В качестве альтернативы, удалите непростой x-csrftoken заголовок в целом, и никакой предварительной проверки не потребуется.

Другие вопросы по тегам