Jquery की .ajax () विधि मेरे सत्र कुकी को क्यों नहीं भेज रही है?


338

$.ajax()किसी साइट में लॉग इन करने के बाद , मैं $.ajax()उस साइट पर दूसरा अनुरोध भेजने की कोशिश कर रहा हूं - लेकिन जब मैं फायरबग का उपयोग करके भेजे गए हेडर की जांच करता हूं, तो अनुरोध में कोई सत्र कुकी शामिल नहीं है।

मैं क्या गलत कर रहा हूं?


2
वेब कुकी और फायरबग के पहले पेज कुकी को पकड़ने के बाद अजाक्स की कुकी आ सकती है।
क्रिस

1
मुझे क्या मतलब नहीं मिला लेकिन मैं कह सकता हूं कि अगर मैं ब्राउज़र एड्रेस बार में अनुरोध यूआरएल पेस्ट करता हूं और फायरबग को फिर से जांचता हूं, तो मैं सर्वर को भेजे गए हेडर में कुकी देख सकता हूं। कोई उपाय?
user345625

तो, मुझे लगता है कि ajax भी उसी तरह से ब्राउज़र को हैंडल करेगा
user345625

आपके द्वारा उपयोग किया जाने वाला कोड क्या है?
डीन हार्डिंग

ब्राउज़र अभी भी अजाक्स अनुरोध, jquery या अन्यथा के दौरान सर्वर द्वारा निर्धारित कुकीज़ बना देगा। क्या आपने ajax अनुरोध की प्रतिक्रिया की जांच की और यह सुनिश्चित करने के लिए कि कुकी सर्वर से वापस आ जाए? सर्वर कोड के साथ कोई समस्या हो सकती है जैसे कि यह कुकी आदि को भी सेट नहीं कर रहा है
डेविड

जवाबों:


218

AJAX कॉल केवल कुकी भेजती है यदि आप जिस यूआरएल को कॉल कर रहे हैं वह आपके कॉलिंग स्क्रिप्ट के समान डोमेन पर है।

यह एक क्रॉस डोमेन समस्या हो सकती है।

हो सकता है कि www.domain-a.comजब आपकी कॉलिंग स्क्रिप्ट चालू थी www.domain-b.com(तब दूसरे शब्दों में: आपने क्रॉस डोमेन कॉल किया था, जिस स्थिति में ब्राउज़र आपकी गोपनीयता की रक्षा करने के लिए कोई कुकीज़ नहीं भेजेगा) से एक यूआरएल को कॉल करने की कोशिश की ।

इस मामले में आपके विकल्प हैं:

  • एक छोटा प्रॉक्सी लिखें, जो डोमेन-बी पर रहता है और डोमेन-ए के लिए आपके अनुरोधों को आगे बढ़ाता है। आपका ब्राउज़र आपको प्रॉक्सी को कॉल करने की अनुमति देगा क्योंकि यह कॉलिंग स्क्रिप्ट के समान सर्वर पर है।
    यह प्रॉक्सी तब आपके द्वारा कुकी नाम और मूल्य पैरामीटर को स्वीकार करने के लिए कॉन्फ़िगर किया जा सकता है जिसे वह डोमेन-ए को भेज सकता है। लेकिन इसके लिए काम करने के लिए आपको कुकी का नाम जानना होगा और अपने सर्वर को डोमेन पर महत्व देना चाहिए-प्रमाणीकरण के लिए एक चाहिए।
  • यदि आप JSON ऑब्जेक्ट ला रहे हैं, तो इसके बजाय JSONP अनुरोध का उपयोग करने का प्रयास करें । jQuery इनका समर्थन करता है। लेकिन आपको अपनी सेवा को डोमेन पर बदलने की आवश्यकता है-ताकि यह वैध JSONP प्रतिसाद देता है।

खुशी है कि अगर थोड़ा भी मदद की।


19
यह भी ध्यान देने योग्य है कि कुकीज़ एक विशिष्ट पथ पर सेट की जा सकती हैं, इसलिए यदि आप कुकी के साथ सेट किए गए थे path=/somethingऔर आप पृष्ठ का अनुरोध कर रहे हैं, /anotherतो कुकी नहीं भेजी जाएगी। जब आप पृष्ठ /somethingका अनुरोध करते हैं तो कुकी अपेक्षित के अनुसार भेजी जाएगी। इसलिए कुकी को सेट करने वाले कोड को भी देखें।
स्टाइल जूल 30'13

2
एक jsonp अनुरोध coockies भेज करता है?
अल्बानक्स

1
@albanx हां, अगर मैंने जिन आवश्यकताओं का उल्लेख किया है, वे सेट हैं। यह किसी भी अन्य की तरह एक सामान्य अनुरोध है और इस तरह से कुकीज़ भेजता है।
फ्लू

1
@albanx इस अन्य संबंधित प्रश्न में कस्टम कुकीज़ के साथ JSONP अनुरोध करने का एक उदाहरण शामिल है
एंटोनियोहेरिज़

4
विकिपीडिया पर JSONP के अनुसार > इस दृष्टिकोण को CORS के पक्ष में छोड़ दिया गया
पीटर डोटचेव

388

मैं क्रॉस-डोमेन परिदृश्य में काम कर रहा हूं। लॉगिन के दौरान रिमोट सर्वर सेट-कुकी हेडर के साथ-साथ Access-Control-Allow-Credentialsसेट पर लौटा रहा है।

दूरस्थ सर्वर के लिए अगले अजाक्स कॉल इस कुकी का उपयोग करना चाहिए।

Access-Control-Allow-Credentialsक्रॉस-डोमेन लॉगिंग की अनुमति देने के लिए कॉर्स है। चेक https://developer.mozilla.org/En/HTTP_access_control उदाहरण के लिए।

मेरे लिए यह JQuery में एक बग की तरह लगता है (या अगले संस्करण में कम से कम फीचर-टू-बी)।

अपडेट करें:

  1. AJAX प्रतिक्रिया (उद्धरण: http://aleembawany.com/2006/11/14/anatomy-of-a-well-designed-ajax-login-experience/ ) से कुकीज़ स्वचालित रूप से सेट नहीं हैं।

    क्यों?

  2. आपको मैन्युअल रूप से सेट करने के लिए प्रतिक्रिया से कुकी का मूल्य नहीं मिल सकता है ( 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


8
महान ! मैं इस + सेट एक्सेस-कंट्रोल-अलाउ-क्रेडेंशियल्स हेडर को सर्वर साइड पर सच करने के लिए उपयोग करता हूं
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 से, इन सुझावों के साथ भी सत्र कुकी पास नहीं होता है। (jQuery v2.1.1)
भू

(ऊ) आपने मुझे विभिन्न दर्दनाक घंटों से बचाया। क्या एक सही जवाब! धन्यवाद! मुझे अपनी वेबसाइट के सार्वजनिक रूट .htaccess में इसे जोड़ने की आवश्यकता थी: <IfModule mod_headers.c> हैडर सेट एक्सेस-कंट्रोल-अलाउंस-ओरिजिन " लोकलहोस्ट " हेडर सेट-कंट्रोल-कंट्रोल-क्रेडेंशियल "सच" </ ifModule>
विनय विंश

48

का उपयोग करते हुए

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 "व्यवहार में" बिट।


41

इसे अपने इनिट फ़ंक्शन में रखें:

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

यह काम करेगा।


1
आपने मेरा दिन बचाया! विधि स्तर पर withCredentials ने मेरे लिए काम नहीं किया। लेकिन इस तरह से वैश्विकता आखिरकार काम करती है! धन्यवाद।
पॉलियस मातुलियोनिस

इसके साथ सावधान रहें, क्योंकि यह सभी अनुरोधों के लिए कुकीज़ भेजेगा, अन्य डोमेन के लिए ईथर (जो इस बात की उम्मीद नहीं करता है और एक्सेस-कंट्रोल-अनुमति-क्रेडेंशियल्स की आवश्यकता से असफल अनुरोध)
gdbdable

12

इस प्रश्न पर पहले से ही बहुत अच्छी प्रतिक्रियाएं हैं, लेकिन मैंने सोचा कि यह उस मामले को स्पष्ट करने में सहायक हो सकता है जहां आप सत्र कुकी भेजने की उम्मीद करेंगे क्योंकि कुकी डोमेन मेल खाता है, लेकिन यह इसलिए नहीं भेजा जा रहा है क्योंकि 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

7

अन्य समाधानों की कोशिश करने और अभी भी इसे काम करने के लिए नहीं करने के बाद, मुझे पता चला कि मेरे मामले में समस्या क्या थी। मैंने कंटेंट टाइप को "एप्लिकेशन / जोंस" से "टेक्स्ट / प्लेन" में बदल दिया।

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

4

मुझे भी यही समस्या हो रही थी और कुछ जांच कर रही थी कि मेरी स्क्रिप्ट बस सत्रीय कुकी नहीं बन रही थी।

मुझे ब्राउज़र में सेशनिड कुकी मूल्य को देखकर पता चला कि मेरा फ्रेमवर्क (Django) सत्रीय कुकी को HttpOnly के साथ डिफ़ॉल्ट रूप से पारित कर रहा था। इसका मतलब यह था कि स्क्रिप्ट में सत्र के मूल्य तक पहुंच नहीं थी और इसलिए अनुरोधों के साथ इसे पारित नहीं किया गया था। हास्यास्पद है कि HttpOnly डिफ़ॉल्ट मूल्य होगा जब इतनी सारी चीजें अजाक्स का उपयोग करती हैं जिसे एक्सेस प्रतिबंध की आवश्यकता होगी।

इसे ठीक करने के लिए मैंने एक सेटिंग बदल दी (SESSION_COOKIE_HTTPONLY = गलत) लेकिन अन्य मामलों में यह कुकी पथ पर "HttpOnly" ध्वज हो सकता है


2
यह मत करो। यह क्लाइंट कुकी को सत्र कुकी तक पहुंच की अनुमति देता है जो कि सबसे आम XSS अटैक वेक्टर है। owasp.org/index.php/HttpOnly
जेसन

1

यदि आप localhostलोकलहोस्ट पर या पोर्ट को विकसित कर रहे हैं जैसे कि localhost:8080, ऊपर दिए गए उत्तरों में वर्णित चरणों के अलावा, आपको यह भी सुनिश्चित करने की आवश्यकता है कि आप सेट-कुकी हेडर में एक डोमेन मूल्य नहीं दे रहे हैं।
आप localhostसेट-कुकी शीर्ष लेख में डोमेन सेट नहीं कर सकते - यह गलत है - बस डोमेन को छोड़ दें।

स्पष्ट डोमेन के साथ लोकलहोस्ट पर कुकीज़ देखें और स्थानीय होस्ट में asp.net कुकीज़ क्यों नहीं बनाएंगे?


0

बस अपने 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 उत्तर में दिया गया है


0

मेरे परिदृश्य और समाधान को जोड़ने पर यह किसी और की मदद करता है। मुझे 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:'/'**});

-5

शायद 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");

लॉग में एक गोता और मैं जल्दी से लापता सत्र देखा, जहां कोई कुकी नहीं भेजी गई थी।


मुझे नहीं लगता कि ऊपर दिया गया उदाहरण काम करेगा, क्योंकि जब कोई सत्र कुकी नहीं है, तो $ sn का मूल्य क्या होगा? (एक यादृच्छिक एक, या शायद अशक्त), वैकल्पिक रूप से उपयोगकर्ता session_name(isset($_GET['sess']) ? $_GET['sess'] : null);session_start();इस तरह से उदाहरण के लिए एक GET मान से session_name सेट कर सकते हैं , उन्हें एक काम की चीज मिलेगी
स्टील ब्रेन

यही कारण है कि मैं इस समस्या को कैसे मिला: इस फ़्लैश अपलोडर thingy से पोस्ट करते समय कोई सत्र नहीं। जैसा कि एक जीईटी चर सत्र पहचानकर्ता का उपयोग करना एक बुरा विचार है, और कुकी काम नहीं कर रही थी, मैंने इसे फेंक दिया। कौन परवाह करता है, फ्लैश अतीत की बात है।
एलर्ट वैन कोपरन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.