Після входу через $.ajax()
сайт я намагаюся надіслати другий $.ajax()
запит на цей сайт, але коли я перевіряю заголовки, надіслані за допомогою FireBug, у запит не включається печиво сеансу.
Що я роблю неправильно?
Після входу через $.ajax()
сайт я намагаюся надіслати другий $.ajax()
запит на цей сайт, але коли я перевіряю заголовки, надіслані за допомогою FireBug, у запит не включається печиво сеансу.
Що я роблю неправильно?
Відповіді:
AJAX-дзвінки надсилають файли cookie лише в тому випадку, якщо URL-адреса, яку ви телефонуєте, знаходиться на тому ж домені, що і ваш сценарій виклику.
Це може бути проблема міждоменної галузі.
Можливо, ви спробували зателефонувати за URL-адресою, www.domain-a.com
поки увімкнено ваш скрипт виклику www.domain-b.com
(Іншими словами: ви здійснили перехресний доменний дзвінок, і в такому випадку браузер не надсилає файлів cookie для захисту вашої конфіденційності).
У цьому випадку ваші варіанти:
Радий, якщо це навіть трохи допомогло.
path=/something
і ви запитуєте сторінку, /another
файл cookie не надсилатиметься. Коли ви запитаєте сторінку, /something
файл cookie буде надіслано, як очікувалося. Тому перевірте код, який встановлює файл 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/ )
Чому?
Ви не можете отримати значення файлу 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
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/…
Використання
xhrFields: { withCredentials:true }
як частина мого дзвінка ajax jQuery був лише частиною рішення. Мені також потрібно було, щоб заголовки повернулися у відповідь 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 NB біт "на практиці".
Поставте це у своїй функції 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
Спробувавши інші рішення, і все ще не змусив його працювати, я з’ясував, у чому проблема в моєму випадку. Я змінив contentType з "application / json" на "text / plain".
$.ajax(fullUrl, {
type: "GET",
contentType: "text/plain",
xhrFields: {
withCredentials: true
},
crossDomain: true
});
У мене була ця сама проблема і я робив кілька перевірок, мої сценарії просто не отримували файли cookie.
Я зрозумів, дивлячись на значення файлу cookie sessionid у браузері, що мій фреймворк (Django) передає файли cookie sessionid з HttpOnly за замовчуванням. Це означало, що сценарії не мали доступу до значення sessionid і тому не передавали його разом із запитами. Смішно, що HttpOnly буде типовим значенням, коли так багато речей використовують Ajax, що вимагатиме обмеження доступу.
Щоб виправити це, я змінив налаштування (SESSION_COOKIE_HTTPONLY = Хибне), але в інших випадках це може бути прапор "HttpOnly" на шляху cookie
Якщо ви розробляєте localhost
або використовуєте порт на localhost, такий як localhost:8080
, крім кроків, описаних у відповідях вище, вам також потрібно переконатися, що ви не передаєте значення домену в заголовку Set-Cookie.
Ви не можете встановити домен localhost
у заголовку Set-Cookie - це неправильно - просто опустіть домен.
Дивіться файли cookie на localhost з явним доменом і чому asp.net не створить файли cookie у localhost?
Тільки мої 2 копійки на встановлення проблеми cookie PHPSESSID, коли він знаходиться у localhost та в середовищі розробників. Я здійснюю виклик AJAX до моєї кінцевої точки API REST в lochost. Скажіть, що його адреса mysite.localhost/api/member/login/
(віртуальний господар у моєму середовищі розробників).
Коли я роблю цей запит на " Листоноші" , справи йдуть добре, і PHPSESSID встановлюється з відповіддю.
Коли я запитую цю кінцеву точку через AJAX зі сторінки проксі-сервера Browsersync (наприклад, 122.133.1.110:3000/test/api/login.php
в адресному рядку мого браузера, див. Домен відрізняється від mysite.localhost
). PHPSESSID не з’являється серед файлів cookie.
Коли я роблю цей запит безпосередньо зі сторінки в тому ж домені (тобто mysite.localhost/test/api/login.php
) PHPSESSID встановлюється просто.
Таким чином, це питання cookie-запиту про походження з різним походженням, як зазначено у відповіді @flu вище
Додаю мій сценарій та рішення, якщо це допомагає комусь іншому. Я зіткнувся з подібним випадком під час використання API RESTful. Мій веб-сервер, на якому розміщені файли HTML / Script / CSS, та API-файли серверів додатків, розміщені в одному домені. Однак шлях був іншим.
Веб - сервер - MYDOMAIN / веб - сторінок /abc.html
використовували abc.js, який встановлював файл cookie з ім'ям mycookie
сервер додатків - mydomain / webapis / ім'я служби .
на які були здійснені дзвінки з апі
Я очікував, що файл cookie буде в mydomain / webapis / servicename і спробував його прочитати, але він не надсилався. Прочитавши коментар з відповіді, я перевірив у інструменті розробки браузера, що шлях mycookie встановлено на "/ веб-сторінки " і, отже, недоступний при виклику служби для
мідомен / webapis / ім'я_служби
Отже, встановлюючи файл cookie з jquery, це те, що я зробив -
$.cookie("mycookie","mayvalue",{**path:'/'**});
Можливо, не на 100% відповідаючи на питання, але я натрапив на цю нитку з надією вирішити проблему сеансу, коли ajax-опублікував завантаження файлів від менеджера ресурсів редактора inovastudio. Зрештою рішення було простим: у них є флеш-завантажувач. Відключення цього (налаштування
var flashUpload = false;
в активі.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 не надсилалося.
session_name(isset($_GET['sess']) ? $_GET['sess'] : null);session_start();
таким чином, вони отримають робочу річ