$.ajax()
किसी साइट में लॉग इन करने के बाद , मैं $.ajax()
उस साइट पर दूसरा अनुरोध भेजने की कोशिश कर रहा हूं - लेकिन जब मैं फायरबग का उपयोग करके भेजे गए हेडर की जांच करता हूं, तो अनुरोध में कोई सत्र कुकी शामिल नहीं है।
मैं क्या गलत कर रहा हूं?
$.ajax()
किसी साइट में लॉग इन करने के बाद , मैं $.ajax()
उस साइट पर दूसरा अनुरोध भेजने की कोशिश कर रहा हूं - लेकिन जब मैं फायरबग का उपयोग करके भेजे गए हेडर की जांच करता हूं, तो अनुरोध में कोई सत्र कुकी शामिल नहीं है।
मैं क्या गलत कर रहा हूं?
जवाबों:
AJAX कॉल केवल कुकी भेजती है यदि आप जिस यूआरएल को कॉल कर रहे हैं वह आपके कॉलिंग स्क्रिप्ट के समान डोमेन पर है।
यह एक क्रॉस डोमेन समस्या हो सकती है।
हो सकता है कि www.domain-a.com
जब आपकी कॉलिंग स्क्रिप्ट चालू थी www.domain-b.com
(तब दूसरे शब्दों में: आपने क्रॉस डोमेन कॉल किया था, जिस स्थिति में ब्राउज़र आपकी गोपनीयता की रक्षा करने के लिए कोई कुकीज़ नहीं भेजेगा) से एक यूआरएल को कॉल करने की कोशिश की ।
इस मामले में आपके विकल्प हैं:
खुशी है कि अगर थोड़ा भी मदद की।
path=/something
और आप पृष्ठ का अनुरोध कर रहे हैं, /another
तो कुकी नहीं भेजी जाएगी। जब आप पृष्ठ /something
का अनुरोध करते हैं तो कुकी अपेक्षित के अनुसार भेजी जाएगी। इसलिए कुकी को सेट करने वाले कोड को भी देखें।
मैं क्रॉस-डोमेन परिदृश्य में काम कर रहा हूं। लॉगिन के दौरान रिमोट सर्वर सेट-कुकी हेडर के साथ-साथ Access-Control-Allow-Credentials
सेट पर लौटा रहा है।
दूरस्थ सर्वर के लिए अगले अजाक्स कॉल इस कुकी का उपयोग करना चाहिए।
Access-Control-Allow-Credentials
क्रॉस-डोमेन लॉगिंग की अनुमति देने के लिए कॉर्स है। चेक https://developer.mozilla.org/En/HTTP_access_control उदाहरण के लिए।
मेरे लिए यह JQuery में एक बग की तरह लगता है (या अगले संस्करण में कम से कम फीचर-टू-बी)।
अपडेट करें:
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"
।
उत्तर:
आपको http://api.jquery.com/jQuery.ajax/ केxhrFields
परम का उपयोग करना चाहिए
प्रलेखन में उदाहरण है:
$.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 }
मेरे jQuery के ajax कॉल के भाग के रूप में समाधान का केवल एक हिस्सा था। मुझे अपने संसाधन से विकल्प की प्रतिक्रिया में हेडर वापस लाने की आवश्यकता है:
Access-Control-Allow-Origin : http://www.wombling.com
Access-Control-Allow-Credentials : true
यह महत्वपूर्ण है कि केवल था एक की अनुमति दी "मूल" प्रतिक्रिया हेडर में था के विकल्प कहते हैं और नहीं "*"। मैंने अनुरोध से मूल को पढ़कर और प्रतिक्रिया में इसे वापस करके इसे प्राप्त किया - शायद प्रतिबंध के मूल कारण को दरकिनार कर दिया, लेकिन मेरे उपयोग के मामले में सुरक्षा सर्वोपरि नहीं है।
मुझे लगा कि यह केवल एक मूल के लिए आवश्यकता का स्पष्ट रूप से उल्लेख करने लायक है, क्योंकि W3C मानक अंतरिक्ष से अलग सूची के लिए अनुमति देता है -लेकिन क्रोम नहीं करता है! http://www.w3.org/TR/cors/#access-control-allow-origin-response-header NB "व्यवहार में" बिट।
इसे अपने इनिट फ़ंक्शन में रखें:
$.ajaxSetup({
xhrFields: {
withCredentials: true
}
});
यह काम करेगा।
इस प्रश्न पर पहले से ही बहुत अच्छी प्रतिक्रियाएं हैं, लेकिन मैंने सोचा कि यह उस मामले को स्पष्ट करने में सहायक हो सकता है जहां आप सत्र कुकी भेजने की उम्मीद करेंगे क्योंकि कुकी डोमेन मेल खाता है, लेकिन यह इसलिए नहीं भेजा जा रहा है क्योंकि AJAX अनुरोध है एक अलग उपडोमेन के लिए बनाया जा रहा है। इस स्थिति में, मेरे पास एक कुकी है जिसे * .mydomain.com डोमेन को सौंपा गया है , और मैं इसे AJAX अनुरोध में अलग-अलग . mydomain.com में शामिल करना चाहता हूं । "डिफ़ॉल्ट रूप से, कुकी नहीं भेजी जाती है। इस समस्या को हल करने के लिए आपको HTTP कुकी को सत्र कुकी पर अक्षम करने की आवश्यकता नहीं है। आपको केवल वही करने की आवश्यकता है जो सुझाव दिया गया है ( 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
अन्य समाधानों की कोशिश करने और अभी भी इसे काम करने के लिए नहीं करने के बाद, मुझे पता चला कि मेरे मामले में समस्या क्या थी। मैंने कंटेंट टाइप को "एप्लिकेशन / जोंस" से "टेक्स्ट / प्लेन" में बदल दिया।
$.ajax(fullUrl, {
type: "GET",
contentType: "text/plain",
xhrFields: {
withCredentials: true
},
crossDomain: true
});
मुझे भी यही समस्या हो रही थी और कुछ जांच कर रही थी कि मेरी स्क्रिप्ट बस सत्रीय कुकी नहीं बन रही थी।
मुझे ब्राउज़र में सेशनिड कुकी मूल्य को देखकर पता चला कि मेरा फ्रेमवर्क (Django) सत्रीय कुकी को HttpOnly के साथ डिफ़ॉल्ट रूप से पारित कर रहा था। इसका मतलब यह था कि स्क्रिप्ट में सत्र के मूल्य तक पहुंच नहीं थी और इसलिए अनुरोधों के साथ इसे पारित नहीं किया गया था। हास्यास्पद है कि HttpOnly डिफ़ॉल्ट मूल्य होगा जब इतनी सारी चीजें अजाक्स का उपयोग करती हैं जिसे एक्सेस प्रतिबंध की आवश्यकता होगी।
इसे ठीक करने के लिए मैंने एक सेटिंग बदल दी (SESSION_COOKIE_HTTPONLY = गलत) लेकिन अन्य मामलों में यह कुकी पथ पर "HttpOnly" ध्वज हो सकता है
यदि आप localhost
लोकलहोस्ट पर या पोर्ट को विकसित कर रहे हैं जैसे कि localhost:8080
, ऊपर दिए गए उत्तरों में वर्णित चरणों के अलावा, आपको यह भी सुनिश्चित करने की आवश्यकता है कि आप सेट-कुकी हेडर में एक डोमेन मूल्य नहीं दे रहे हैं।
आप localhost
सेट-कुकी शीर्ष लेख में डोमेन सेट नहीं कर सकते - यह गलत है - बस डोमेन को छोड़ दें।
स्पष्ट डोमेन के साथ लोकलहोस्ट पर कुकीज़ देखें और स्थानीय होस्ट में asp.net कुकीज़ क्यों नहीं बनाएंगे?
बस अपने 2 सेंट PHPSESSID कुकी मुद्दे को सेट करने पर जब लोकलहोस्ट और देव वातावरण में। मैं लोकेस्ट पर मेरे बाकी एपीआई एंडपॉइंट को AJAX कॉल करता हूं। कहो इसका पता है mysite.localhost/api/member/login/
(मेरे देव पर्यावरण पर पुण्य मेजबान)।
जब मैं पोस्टमैन पर यह अनुरोध करता हूं , तो चीजें ठीक हो जाती हैं और प्रतिक्रिया के साथ PHPSESSID सेट हो जाता है।
जब मैं इस एंडपॉइंट का अनुरोध AJAX के माध्यम से ब्राउजरसिंक प्रॉक्सी पेज (उदाहरण के लिए 122.133.1.110:3000/test/api/login.php
मेरे ब्राउज़र एड्रेस लाइन से करता हूं, तो देखें कि डोमेन अलग है mysite.localhost
) PHPSESSID कुकीज़ के बीच दिखाई नहीं देता है।
जब मैं एक ही डोमेन (यानी mysite.localhost/test/api/login.php
) PHPSESSID पर पृष्ठ से सीधे यह अनुरोध करता हूं तो यह ठीक है।
तो यह एक क्रॉस-ऑरिजनल ओरिजिनल रिक्वेस्ट कुकीज इशू है जैसा कि ऊपर उल्लिखित @flu उत्तर में दिया गया है
मेरे परिदृश्य और समाधान को जोड़ने पर यह किसी और की मदद करता है। मुझे RESTful API का उपयोग करते समय इसी तरह के मामले का सामना करना पड़ा। HTML / Script / CSS फाइलों की मेजबानी करने वाले मेरे वेब सर्वर और एपीआई को उजागर करने वाले एप्लिकेशन सर्वर को एक ही डोमेन पर होस्ट किया गया था। हालाँकि रास्ता अलग था।
वेब सर्वर - mydomain / वेबपेजों /abc.html
abc.js का उपयोग किया जो कुकी को mycookie नाम दिया
ऐप सर्वर - mydomain / webapis / servicename।
जिसमें से आपी कॉल किए गए थे
मैं mydomain / webapis / servicename में कुकी की उम्मीद कर रहा था और इसे पढ़ने की कोशिश कर रहा था लेकिन इसे भेजा नहीं जा रहा था। जवाब से टिप्पणी पढ़ने के बाद, मैं ब्राउज़र के विकास उपकरण में जाँच की है कि mycookie के पथ "/ करने के लिए स्थापित किया गया था वेबपेजों " और इसलिए करने के लिए सेवा कॉल में उपलब्ध नहीं
mydomain / webapis / servicename
तो जबकि jquery से कुकी की स्थापना, यह वही है जो मैंने किया -
$.cookie("mycookie","mayvalue",{**path:'/'**});
शायद 100% सवाल का जवाब नहीं दे रहा है, लेकिन मैं इस समस्या को एक सत्र की समस्या को हल करने की उम्मीद में ठोकर खा गया, जब अजाक्स-इनोवेशनस्टडियो संपादक के एसेटमैन से फाइलअपलोड कर रहा था। अंततः समाधान सरल था: उनके पास एक फ्लैश-अपलोडर है। उसको अक्षम करना (सेटिंग)
var flashUpload = false;
in परिसंपत्ति .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");
लॉग में एक गोता और मैं जल्दी से लापता सत्र देखा, जहां कोई कुकी नहीं भेजी गई थी।
session_name(isset($_GET['sess']) ? $_GET['sess'] : null);session_start();
इस तरह से उदाहरण के लिए एक GET मान से session_name सेट कर सकते हैं , उन्हें एक काम की चीज मिलेगी