Почему метод jQuery .ajax () не отправляет мой cookie сеанса?

После входа в систему через $.ajax() на сайт, я пытаюсь отправить второй $.ajax() на этот сайт, но когда я проверяю заголовки, отправленные с использованием FireBug, в запрос не входит cookie сеанса ,

Что я делаю не так?

AJAX вызывает только отправку Cookies, если URL-адрес, который вы вызываете, находится в том же домене, что и ваш сценарий вызова.

Это может быть проблема с перекрестными доменами.

Возможно, вы попытались вызвать URL-адрес с www.domain-a.com пока ваш сценарий звонков был на www.domain-b.com (другими словами: вы сделали перекрестный доменный звонок, и в этом случае браузер не будет отправлять cookies для защиты вашей конфиденциальности).

В этом случае ваши варианты:

  • Напишите небольшой прокси-сервер, который находится на домене-b и перенаправляет ваши запросы в домен-a. Ваш браузер позволит вам вызвать прокси-сервер, потому что он находится на том же сервере, что и вызывающий скрипт.
    Затем этот прокси-сервер может быть настроен вами, чтобы принять имя и значение файла cookie, которое он может отправить в домен-a. Но для этого вам нужно знать имя файла cookie и оценивать свой сервер на домене – необходимость аутентификации.
  • Если вы извлекаете объекты JSON, попробуйте вместо этого использовать запрос JSONP . jQuery поддерживает их. Но вам нужно изменить свою службу на домен-а так, чтобы она возвращала действительные ответы JSONP.

Рад, если это помогло даже немного.

Я работаю в междоменном сценарии. Во время входа в систему удаленный сервер возвращает заголовок Set-Cookie вместе с Access-Control-Allow-Credentials true.

Следующий вызов ajax для удаленного сервера должен использовать этот файл cookie.

Access-Control-Allow-Credentials учетным записям CORS Access-Control-Allow-Credentials позволяет регистрировать междоменные протоколы. Для примера рассмотрите https://developer.mozilla.org/En/HTTP_access_control .

Для меня это похоже на ошибку в JQuery (или, по крайней мере, функцию, которая будет в следующей версии).

ОБНОВИТЬ:

  1. Файлы cookie автоматически не устанавливаются из ответа AJAX (ссылка: http://aleembawany.com/2006/11/14/anatomy-of-a-well-designed-ajax-login-experience/ )

    Зачем?

  2. Вы не можете получить значение cookie из ответа, чтобы установить его вручную ( http://www.w3.org/TR/XMLHttpRequest/#dom-xmlhttprequest-getresponseheader )

    Я смущен..

    Должен существовать способ задать jquery.ajax() для установки параметра XMLHttpRequest.withCredentials = "true" .

ОТВЕТ: Вы должны использовать параметр xhrFields для http://api.jquery.com/jQuery.ajax/

Пример в документации:

 $.ajax({ url: a_cross_domain_url, xhrFields: { withCredentials: true } }); 

Важно также, чтобы сервер правильно ответил на этот запрос. Копирование здесь замечательных комментариев от @ Frédéric и @Pebbl:

Important note: when responding to a credentialed request, server must specify a domain, and cannot use wild carding. The above example would fail if the header was wildcarded as: Access-Control-Allow-Origin: *

Поэтому, когда запрос:

 Origin: http://foo.example Cookie: pageAccess=2 

Сервер должен отвечать:

 Access-Control-Allow-Origin: http://foo.example Access-Control-Allow-Credentials: true [payload] 

В противном случае полезная нагрузка не будет возвращена скрипту. См. https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials.

С помощью

 xhrFields: { withCredentials:true } 

как часть моего jQuery, вызов ajax был только частью решения. Мне также нужно было вернуть заголовки в ответ OPTIONS от моего ресурса:

 Access-Control-Allow-Origin : http://www.wombling.com Access-Control-Allow-Credentials : true 

Было важно, чтобы в заголовке ответа вызова OPTIONS разрешалось только одно допустимое «происхождение», а не «*». Я достиг этого, прочитав исходный код из запроса и заполнив его обратно в ответ – возможно, обойти первоначальную причину ограничения, но в моем случае защита не имеет первостепенной важности.

Я думал, что стоит явно указать требование только для одного источника, поскольку стандарт W3C позволяет использовать список, разделенный пробелами, – но Chrome не делает этого! http://www.w3.org/TR/cors/#access-control-allow-origin-response-header Обратите внимание на бит “на практике”.

Поместите это в свою функцию init:

 $.ajaxSetup({ xhrFields: { withCredentials: true } }); 

Это будет работать.

Уже есть много хороших ответов на этот вопрос, но я подумал, что может быть полезно прояснить случай, когда вы ожидаете, что cookie сеанса будет отправлен, потому что домен cookie совпадает, но он не отправляется, поскольку запрос AJAX делается для другого поддомена. В этом случае у меня есть файл cookie, который присваивается домену * .mydomain.com , и я хочу, чтобы он был включен в запрос AJAX для different.mydomain.com ». По умолчанию cookie не отправляется. Вам не нужно отключать HTTPONLY в cookie сеанса, чтобы решить эту проблему. Вам нужно всего лишь сделать то, что предложило предложение ( https://stackoverflow.com/a/23660618/545223 ), и сделать следующее.

1) Добавьте в свой запрос ajax следующее.

 xhrFields: { withCredentials:true } 

2) Добавьте в свои заголовки ответов следующие ресурсы для разных субдоменов.

 Access-Control-Allow-Origin : http://original.mydomain.com Access-Control-Allow-Credentials : true 

У меня была такая же проблема, и я делал некоторые проверки, мой скрипт просто не получал cookie sessionid.

Я понял, посмотрев на значение cookie sessionid в браузере, когда моя инфраструктура (Django) передавала cookie sessionid с HttpOnly по умолчанию. Это означало, что скрипты не имели доступа к значению sessionid и поэтому не передавали его вместе с запросами. Вид смешного, что HttpOnly будет значением по умолчанию, когда так много вещей использует Ajax, для которого требуется ограничение доступа.

Чтобы исправить это, я изменил настройку (SESSION_COOKIE_HTTPONLY = False), но в других случаях это может быть флаг HttpOnly на пути к файлу cookie

Пробовав другие решения и до сих пор не работая, я выяснил, в чем проблема. Я изменил contentType с «application / json» на «text / plain».

 $.ajax(fullUrl, { type: "GET", contentType: "text/plain", xhrFields: { withCredentials: true }, crossDomain: true }); 

Если вы разрабатываете localhost или порт на локальном хосте, таком как localhost:8080 , в дополнение к шагам, описанным в ответах выше, вам также необходимо убедиться, что вы не передаете значение домена в заголовке Set-Cookie.
Вы не можете установить домен в localhost в заголовке Set-Cookie – это неверно – просто опустите домен.

См. Cookies на localhost с явным доменом и почему ASP.NET не создает cookies в localhost?

Перед попыткой входа в систему вы должны инициализировать сеанс.

Для php вам нужно сделать

 session_start(); 

на странице, с которой вы начинаете вход в систему ajax.

Так что SESSIONID будет создан и сохранен cookie браузера. И отправляется вместе с заголовком запроса во время вызова ajax, если вы делаете запрос ajax в тот же домен

Для последовательных вызовов ajax браузер будет использовать SESSIONID который был создан и сохранен первоначально в cookie браузера, если мы не очистим cookie браузера или не выйдем из системы (или не установим другой файл cookie)

Возможно, не 100% ответили на вопрос, но я наткнулся на этот stream в надежде решить проблему сеанса, когда ajax-posting fileupload от управляющего ресурсами редактора Innovastudio. В конце концов решение было простым: у них есть флеш-загрузчик. Отключение этого (установка

 var flashUpload = false; 

в файле asset.php), и свет снова начал мигать.

Поскольку эти проблемы могут быть очень трудными для отладки, я обнаружил, что в обработчике загрузки будет добавлено что-то вроде следующего: вы, ну, в данном случае, на правильном пути:

 $sn=session_name(); error_log("session_name: $sn "); if(isset($_GET[$sn])) error_log("session as GET param"); if(isset($_POST[$sn])) error_log("session as POST param"); if(isset($_COOKIE[$sn])) error_log("session as Cookie"); if(isset($PHPSESSID)) error_log("session as Global"); 

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

Давайте будем гением компьютера.