Почему метод jaery .ajax () не отправляет мой сеансовый cookie?
338
После входа в систему через $.ajax()сайт я пытаюсь отправить второй $.ajax()запрос на этот сайт, но когда я проверяю заголовки, отправленные с помощью FireBug, в запрос не включается файл cookie сеанса.
Файл cookie ajax может появиться после веб-файла cookie, и FireBug может перехватить файл cookie первой страницы.
Крис
1
Я не понял, что вы имеете в виду, но я могу сказать, если я вставлю URL-адрес запроса в адресную строку браузера и снова проверю Firebug, я могу увидеть cookie в заголовках, отправленных на сервер. Какие-либо решения?
user345625
Итак, я думаю, что ajax будет обрабатывать так же, как браузер
user345625
Какой код вы используете?
Дин Хардинг
браузер по-прежнему будет создавать файлы cookie, установленные сервером во время запроса ajax, jquery или иным образом. Вы проверили ответ на запрос ajax и убедились, что файлы cookie возвращаются с сервера, который нужно настроить?
David
Ответы:
218
Вызовы AJAX отправляют Cookies только в том случае, если URL-адрес, по которому вы звоните, находится в том же домене, что и ваш скрипт вызова.
Это может быть междоменной проблемой.
Возможно, вы пытались вызвать URL-адрес, www.domain-a.comкогда был включен сценарий вызова www.domain-b.com(другими словами: вы сделали междоменный вызов, и в этом случае браузер не будет отправлять файлы cookie для защиты вашей конфиденциальности).
В этом случае ваши варианты:
Напишите небольшой прокси, который находится на домене-b и перенаправляет ваши запросы на домен-a. Ваш браузер позволит вам вызывать прокси, потому что он находится на том же сервере, что и вызывающий скрипт. Затем вы можете настроить этот прокси-сервер так, чтобы он принимал имя файла cookie и параметр значения, которые он может отправлять в домен a. Но для того, чтобы это работало, вам нужно знать имя куки-файла и значение вашего сервера в домене-a, требующем аутентификации.
Если вы выбираете объекты JSON, попробуйте вместо этого использовать запрос JSONP . JQuery поддерживает это. Но вам нужно изменить свой сервис в домене-a, чтобы он возвращал действительные ответы JSONP.
Стоит также отметить, что файлы cookie могут быть установлены по определенному пути, поэтому, если для файла cookie установлено значение path=/somethingи вы запрашиваете страницу, /anotherфайл cookie не будет отправлен. Когда вы запрашиваете страницу, /somethingкуки будут отправлены, как ожидалось. Так что проверьте код, который также устанавливает cookie.
Styfle
2
JSONP-запрос отправляет куки?
albanx
1
@albanx Да, если указанные выше требования установлены. Это обычный запрос, как и любой другой, который отправляет куки.
грипп
1
@albanx этот другой связанный вопрос включает пример того, как выполнить этот запрос JSONP с помощью пользовательских файлов cookie
AntonioHerraizS
4
Согласно JSONP в Википедии> от этого подхода отказались в пользу CORS
Петр Дотчев
388
Я работаю в междоменном сценарии. При входе в систему удаленный сервер возвращает заголовок Set-Cookie и Access-Control-Allow-Credentialsзначение true.
Следующий ajax-вызов на удаленный сервер должен использовать этот файл cookie.
Также важно, чтобы сервер правильно отвечал на этот запрос. Копирование здесь замечательных комментариев от @ 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: *
Большой ! Я добавляю для использования этого + установить заголовок Access-Control-Allow-Credentials в значение true на стороне сервера
Frédéric
и где я могу установить эти учетные данные ?, при авторизации заголовка ?, в теле запроса?
Франциско Корралес Моралес
3
Спасибо за ответ :) просто быстрое дополнение, возможно, стоит упомянуть 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: *developer.mozilla.org/en-US/docs/Web/HTTP/…
Pebbl
Ничто из этого не сработало для меня, к сожалению. Если я выполняю тот же запрос от AngularJS, он работает, но из jQuery, даже с этими предложениями сеансовый Cookie не передается. (jQuery v2.1.1)
геоидезическая
(OO) Вы спасли меня от различных мучительных часов. Какой идеальный ответ! Спасибо! Мне нужно было добавить их в общий корневой каталог .htaccess моего веб-сайта: <IfModule mod_headers.c> Набор заголовков Access-Control-Allow-Origin " localhost " Набор заголовков Access-Control-Allow-Credentials "true" </ IfModule>
Vinay Vissh
48
С помощью
xhrFields:{ withCredentials:true}
как часть моего вызова jQuery ajax была только частью решения. Мне также нужно было вернуть заголовки в ответе OPTIONS от моего ресурса:
Было важно, чтобы в заголовке ответа на вызов OPTIONS был только один допустимый «источник», а не «*». Я добился этого, прочитав происхождение из запроса и вставив его обратно в ответ - возможно, обойдя исходную причину ограничения, но в моем случае использования безопасность не имеет первостепенного значения.
Ты спас мой день! На уровне метода withCredentials у меня не работает. Но глобально, как это, это наконец работает! Спасибо.
Паулюс Матулионис
будьте осторожны с этим, потому что он будет отправлять файлы cookie для всех запросов, эфир для других доменов (чего не следует ожидать, и отказывать в запросе по требованию Access-Control-Allow-Credentials)
gdbdable
12
На этот вопрос уже есть много хороших ответов, но я подумал, что было бы полезно прояснить случай, когда вы ожидаете, что cookie-файл сеанса будет отправлен, потому что домен cookie-файлов совпадает, но он не отправляется, потому что запрос AJAX делается на другой поддомен. В этом случае, у меня есть печенье , который назначен на * .mydomain.com домена, и я хотел , чтобы быть включенным в запросе AJAX к different.mydomain.com ». По умолчанию, куки не присылают. Вам не нужно отключать HTTPONLY в файле cookie сеанса, чтобы решить эту проблему. Вам нужно только сделать то, что предложено вомблинг ( https://stackoverflow.com/a/23660618/545223 ), и сделать следующее.
1) Добавьте следующее в ваш запрос ajax.
xhrFields:{ withCredentials:true}
2) Добавьте следующее в заголовки ответа для ресурсов в другом поддомене.
Испытав другие решения и все еще не заставив их работать, я выяснил, в чем проблема в моем случае. Я изменил contentType с «application / json» на «text / plain».
У меня возникла та же проблема, и при некоторых проверках мой сценарий просто не получал cookie-файл sessionid.
По значению cookie-файла sessionid в браузере я выяснил, что мой фреймворк (Django) передавал cookie-файл sessionid с HttpOnly по умолчанию. Это означало, что скрипты не имели доступа к значению sessionid и поэтому не передавали его вместе с запросами. Довольно смешно, что HttpOnly будет значением по умолчанию, когда так много вещей используют Ajax, что потребует ограничения доступа.
Чтобы исправить это, я изменил настройку (SESSION_COOKIE_HTTPONLY = False), но в других случаях это может быть флаг «HttpOnly» на пути к cookie
Не делай этого. Это позволяет клиентскому сценарию получить доступ к куки-файлу сеанса, который является наиболее распространенным вектором атаки XSS. owasp.org/index.php/HttpOnly
Джейсон Элкин
1
Если вы разрабатываете localhostпорт или локальный хост, например localhost:8080, в дополнение к шагам, описанным в ответах выше, вам также нужно убедиться, что вы не передаете значение домена в заголовке Set-Cookie.
Вы не можете установить домен localhostв заголовке Set-Cookie - это неправильно - просто опустите домен.
Просто мои 2 цента при установке файла cookie PHPSESSID при работе на локальном хосте и в среде разработчика. Я делаю AJAX-вызов к моей конечной точке REST API на locahost. Скажите, что его адрес mysite.localhost/api/member/login/(виртуальный хост в моей среде разработки).
Когда я делаю этот запрос на Почтальон , все идет хорошо, и PHPSESSID устанавливается с ответом.
Когда я запрашиваю эту конечную точку через AJAX со страницы прокси- сервера Browsersync (например, 122.133.1.110:3000/test/api/login.phpв адресной строке моего браузера вижу, что домен отличается от vs mysite.localhost) PHPSESSID не появляется среди файлов cookie.
Когда я делаю этот запрос прямо со страницы в том же домене (то есть mysite.localhost/test/api/login.php) PHPSESSID устанавливается просто отлично.
Так что это проблема с файлами cookie для запросов на отправку из разных источников, как упоминалось в ответе @flu выше
Добавление моего сценария и решения на случай, если это поможет кому-то еще. Я сталкивался с подобным случаем при использовании RESTful API. Мой веб-сервер, на котором размещены файлы HTML / Script / CSS и API-интерфейсы сервера приложений, размещался в одном домене. Однако путь был другим.
веб-сервер - mydomain / webpages /abc.html
использовал abc.js, который установил cookie с именем mycookie
Я ожидал файл cookie в mydomain / webapis / servicename и попытался прочитать его, но он не отправлялся. Прочитав комментарий к ответу, я проверил в инструменте разработки браузера, что путь mycookie был установлен на "/ webpages " и, следовательно, недоступен при вызове службы для
mydomain / webapis / servicename
Так что, устанавливая cookie из jquery, я так и сделал -
Возможно, не на 100% отвечая на вопрос, но я наткнулся на эту ветку в надежде решить проблему сеанса, когда ajax публикует загрузку файла из менеджера активов редактора 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 сеанса, каким будет значение $ sn? (случайный или, может быть, ноль), в качестве альтернативы пользователи могут установить session_name из значения GET, например, session_name(isset($_GET['sess']) ? $_GET['sess'] : null);session_start();таким образом, они получат работающую вещь
Steel Brain
Это именно то, как я нашел проблему: нет сессий при отправке с этого Flash Uploader вещь. Поскольку использование идентификатора сеанса переменной GET - плохая идея, и cookie не работает, я его выбросил. Кого волнует, вспышка остается в прошлом в любом случае.
Ответы:
Вызовы AJAX отправляют Cookies только в том случае, если URL-адрес, по которому вы звоните, находится в том же домене, что и ваш скрипт вызова.
Это может быть междоменной проблемой.
Возможно, вы пытались вызвать URL-адрес,
www.domain-a.com
когда был включен сценарий вызоваwww.domain-b.com
(другими словами: вы сделали междоменный вызов, и в этом случае браузер не будет отправлять файлы cookie для защиты вашей конфиденциальности).В этом случае ваши варианты:
Затем вы можете настроить этот прокси-сервер так, чтобы он принимал имя файла cookie и параметр значения, которые он может отправлять в домен a. Но для того, чтобы это работало, вам нужно знать имя куки-файла и значение вашего сервера в домене-a, требующем аутентификации.
Рад, что это помогло хоть немного.
источник
path=/something
и вы запрашиваете страницу,/another
файл cookie не будет отправлен. Когда вы запрашиваете страницу,/something
куки будут отправлены, как ожидалось. Так что проверьте код, который также устанавливает cookie.Я работаю в междоменном сценарии. При входе в систему удаленный сервер возвращает заголовок Set-Cookie и
Access-Control-Allow-Credentials
значение true.Следующий ajax-вызов на удаленный сервер должен использовать этот файл cookie.
CORS
Access-Control-Allow-Credentials
позволяют вести междоменную регистрацию. Проверьте https://developer.mozilla.org/En/HTTP_access_control для примеров.Для меня это похоже на ошибку в JQuery (или, по крайней мере, в следующей версии).
ОБНОВИТЬ:
Файлы cookie не устанавливаются автоматически из ответа AJAX (ссылка: http://aleembawany.com/2006/11/14/anatomy-of-a-well-designed-ajax-login-experience/ )
Зачем?
Вы не можете получить значение куки из ответа, чтобы установить его вручную ( http://www.w3.org/TR/XMLHttpRequest/#dom-xmlhttprequest-getresponseheader )
Я запутался..
Там должен существовать способ задать
jquery.ajax()
для набораXMLHttpRequest.withCredentials = "true"
параметров.ОТВЕТ: Вы должны использовать
xhrFields
параметр http://api.jquery.com/jQuery.ajax/Пример в документации:
Также важно, чтобы сервер правильно отвечал на этот запрос. Копирование здесь замечательных комментариев от @ 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: *
Итак, когда запрос
Сервер должен ответить:
В противном случае полезная нагрузка не будет возвращена в сценарий. Смотрите: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials
источник
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: *
developer.mozilla.org/en-US/docs/Web/HTTP/…С помощью
как часть моего вызова jQuery ajax была только частью решения. Мне также нужно было вернуть заголовки в ответе OPTIONS от моего ресурса:
Было важно, чтобы в заголовке ответа на вызов OPTIONS был только один допустимый «источник», а не «*». Я добился этого, прочитав происхождение из запроса и вставив его обратно в ответ - возможно, обойдя исходную причину ограничения, но в моем случае использования безопасность не имеет первостепенного значения.
Я подумал, что стоит явно указать требование только для одного источника, поскольку стандарт W3C допускает разделенный пробелами список, но Chrome нет! http://www.w3.org/TR/cors/#access-control-allow-origin-response-header NB Бит "на практике".
источник
Поместите это в вашу функцию инициализации:
Это сработает.
источник
На этот вопрос уже есть много хороших ответов, но я подумал, что было бы полезно прояснить случай, когда вы ожидаете, что cookie-файл сеанса будет отправлен, потому что домен cookie-файлов совпадает, но он не отправляется, потому что запрос AJAX делается на другой поддомен. В этом случае, у меня есть печенье , который назначен на * .mydomain.com домена, и я хотел , чтобы быть включенным в запросе AJAX к different.mydomain.com ». По умолчанию, куки не присылают. Вам не нужно отключать HTTPONLY в файле cookie сеанса, чтобы решить эту проблему. Вам нужно только сделать то, что предложено вомблинг ( https://stackoverflow.com/a/23660618/545223 ), и сделать следующее.
1) Добавьте следующее в ваш запрос ajax.
2) Добавьте следующее в заголовки ответа для ресурсов в другом поддомене.
источник
Испытав другие решения и все еще не заставив их работать, я выяснил, в чем проблема в моем случае. Я изменил contentType с «application / json» на «text / plain».
источник
У меня возникла та же проблема, и при некоторых проверках мой сценарий просто не получал cookie-файл sessionid.
По значению cookie-файла sessionid в браузере я выяснил, что мой фреймворк (Django) передавал cookie-файл sessionid с HttpOnly по умолчанию. Это означало, что скрипты не имели доступа к значению sessionid и поэтому не передавали его вместе с запросами. Довольно смешно, что HttpOnly будет значением по умолчанию, когда так много вещей используют Ajax, что потребует ограничения доступа.
Чтобы исправить это, я изменил настройку (SESSION_COOKIE_HTTPONLY = False), но в других случаях это может быть флаг «HttpOnly» на пути к cookie
источник
Если вы разрабатываете
localhost
порт или локальный хост, напримерlocalhost:8080
, в дополнение к шагам, описанным в ответах выше, вам также нужно убедиться, что вы не передаете значение домена в заголовке Set-Cookie.Вы не можете установить домен
localhost
в заголовке Set-Cookie - это неправильно - просто опустите домен.См. Cookies на локальном хосте с явным доменом и Почему asp.net не создает куки на локальном хосте?
источник
Просто мои 2 цента при установке файла cookie PHPSESSID при работе на локальном хосте и в среде разработчика. Я делаю AJAX-вызов к моей конечной точке REST API на locahost. Скажите, что его адрес
mysite.localhost/api/member/login/
(виртуальный хост в моей среде разработки).Когда я делаю этот запрос на Почтальон , все идет хорошо, и PHPSESSID устанавливается с ответом.
Когда я запрашиваю эту конечную точку через AJAX со страницы прокси- сервера Browsersync (например,
122.133.1.110:3000/test/api/login.php
в адресной строке моего браузера вижу, что домен отличается от vsmysite.localhost
) PHPSESSID не появляется среди файлов cookie.Когда я делаю этот запрос прямо со страницы в том же домене (то есть
mysite.localhost/test/api/login.php
) PHPSESSID устанавливается просто отлично.Так что это проблема с файлами cookie для запросов на отправку из разных источников, как упоминалось в ответе @flu выше
источник
Добавление моего сценария и решения на случай, если это поможет кому-то еще. Я сталкивался с подобным случаем при использовании RESTful API. Мой веб-сервер, на котором размещены файлы HTML / Script / CSS и API-интерфейсы сервера приложений, размещался в одном домене. Однако путь был другим.
использовал abc.js, который установил cookie с именем mycookie
на которые были сделаны вызовы API
Я ожидал файл cookie в mydomain / webapis / servicename и попытался прочитать его, но он не отправлялся. Прочитав комментарий к ответу, я проверил в инструменте разработки браузера, что путь mycookie был установлен на "/ webpages " и, следовательно, недоступен при вызове службы для
Так что, устанавливая cookie из jquery, я так и сделал -
источник
Возможно, не на 100% отвечая на вопрос, но я наткнулся на эту ветку в надежде решить проблему сеанса, когда ajax публикует загрузку файла из менеджера активов редактора innovastudio. В конце концов решение было простым: у них есть флэш-загрузчик. Отключение этого (настройка
в asset.php) и огни снова начали мигать.
Поскольку эти проблемы могут быть очень сложными для отладки, я обнаружил, что если поместить что-то вроде следующего в обработчик загрузки, то вы (в данном случае и я) окажетесь на правильном пути:
Погружение в журнал, и я быстро обнаружил пропущенную сессию, где не было отправлено печенье.
источник
session_name(isset($_GET['sess']) ? $_GET['sess'] : null);session_start();
таким образом, они получат работающую вещь