एक कोर पोस्ट अनुरोध सादे जावास्क्रिप्ट से काम करता है, लेकिन jQuery के साथ क्यों नहीं?


87

मैं एक क्रॉस ओरिजिनल पोस्ट अनुरोध करने की कोशिश कर रहा हूं, और मुझे इसे JavaScriptइस तरह से काम करना पड़ा :

var request = new XMLHttpRequest();
var params = "action=something";
request.open('POST', url, true);
request.onreadystatechange = function() {if (request.readyState==4) alert("It worked!");};
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.setRequestHeader("Content-length", params.length);
request.setRequestHeader("Connection", "close");
request.send(params);

लेकिन मैं उपयोग करना चाहूंगा jQuery, लेकिन मैं इसे काम नहीं कर सकता। यही मैं कोशिश कर रहा हूँ:

$.ajax(url, {
    type:"POST",
    dataType:"json",
    data:{action:"something"}, 
    success:function(data, textStatus, jqXHR) {alert("success");},
    error: function(jqXHR, textStatus, errorThrown) {alert("failure");}
});

इसके परिणामस्वरूप विफलता होती है। अगर किसी को पता है कि jQueryकाम क्यों नहीं करता है, तो कृपया हम सभी को बताएं। धन्यवाद।

(मैं jQuery1.5.1, और फ़ायरफ़ॉक्स 4.0 का उपयोग कर रहा हूं , और मेरा सर्वर उचित Access-Control-Allow-Originहेडर के साथ जवाब दे रहा है )


यह मेरे लिए समाधान था (जावास्क्रिप्ट के XMLHttpRequest का उपयोग करें), जबकि
कॉर्न्स

जवाबों:


73

अद्यतन: जैसा कि टिमके ने बताया, यह 1.5.2 किसी भी अधिक के साथ आवश्यक नहीं है। लेकिन अगर आप कस्टम हेडर जोड़ना चाहते हैं या क्रेडेंशियल (उपयोगकर्ता नाम, पासवर्ड, या कुकीज़, आदि) के उपयोग की अनुमति देते हैं, तो पढ़ें।


मुझे लगता है कि मुझे जवाब मिल गया! (4 घंटे और बाद में बहुत सारे शाप)

//This does not work!!
Access-Control-Allow-Headers: *

आपको उन सभी हेडर को मैन्युअल रूप से निर्दिष्ट करने की आवश्यकता है जिन्हें आप स्वीकार करेंगे (कम से कम मेरे लिए एफएफ 4.0 और क्रोम 10.0.648.204.20) में ऐसा ही था।

jQuery की $ .ajax विधि सभी क्रॉस डोमेन अनुरोधों के लिए "x-request-with" हेडर भेजती है (मुझे लगता है कि यह एकमात्र क्रॉस डोमेन है)।

तो विकल्प अनुरोध का जवाब देने के लिए आवश्यक हैडर गायब है:

//no longer needed as of jquery 1.5.2
Access-Control-Allow-Headers: x-requested-with

यदि आप कोई भी "सरल" हेडर पास कर रहे हैं, तो आपको उन्हें अपनी सूची में शामिल करना होगा (मैं एक और भेज दूंगा):

//only need part of this for my custom header
Access-Control-Allow-Headers: x-requested-with, x-requested-by

तो यह सब एक साथ रखने के लिए, यहाँ मेरा PHP है:

// * wont work in FF w/ Allow-Credentials
//if you dont need Allow-Credentials, * seems to work
header('Access-Control-Allow-Origin: http://www.example.com');
//if you need cookies or login etc
header('Access-Control-Allow-Credentials: true');
if ($this->getRequestMethod() == 'OPTIONS')
{
  header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
  header('Access-Control-Max-Age: 604800');
  //if you need special headers
  header('Access-Control-Allow-Headers: x-requested-with');
  exit(0);
}

5
ध्यान दें कि jQuery 1.5.2 ने अपना व्यवहार बदल दिया है। यह अब "X-Requested-With" हेडर नहीं जोड़ता है, इसलिए यह अब एक मुद्दा नहीं हो सकता है। blog.jquery.com/2011/03/31/jquery-152-released (बग 8423)
मैगमैटिक

1
@ टिम, तुम सही हो! मैंने नोटिस नहीं किया कि वे 1.5.2 जारी करते हैं। यह कहा जा रहा है, यह भी काम करता है अगर आप इसे पूर्व उड़ान की जरूरत है। मैंने अपना उत्तर अपडेट कर दिया है।
विल मेसन

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

1
@ एलिसबेथ यह विधि केवल तभी काम करती है जब आप अनुरोधित गंतव्य को नियंत्रित करते हैं ... यह एक मध्यवर्ती स्क्रिप्ट नहीं है। यह हमारे अनुरोधित स्थान के हमारे PHP का शीर्ष है। क्या यह ज़्यादा सही लगता है?
विल मेसन

2
हाँ! धन्यवाद होगा। मुझे लगा कि आप क्लाइंट की ओर से सब कुछ नियंत्रित कर सकते हैं, लेकिन ऐसा लगता है कि आपको दोनों छोरों पर नियंत्रण की आवश्यकता है।
एलिजाबेथ

18

एक अन्य संभावना यह है कि हेडर dataType: jsonभेजने के लिए सेटिंग JQuery का कारण बनती है Content-Type: application/json। इसे CORS द्वारा एक गैर-मानक हेडर माना जाता है, और इसके लिए CORS प्रीफ़लाइट अनुरोध की आवश्यकता होती है। तो कोशिश करने के लिए कुछ बातें:

1) उचित प्रीफ़्लाइट प्रतिक्रियाओं को भेजने के लिए अपने सर्वर को कॉन्फ़िगर करने का प्रयास करें। यह अतिरिक्त हेडर जैसे Access-Control-Allow-Methodsऔर के रूप में होगा Access-Control-Allow-Headers

2) dataType: jsonसेटिंग ड्रॉप करें । JQuery को Content-Type: application/x-www-form-urlencodedडिफ़ॉल्ट रूप से अनुरोध करना चाहिए , लेकिन बस सुनिश्चित करने के लिए, आप के dataType: jsonसाथ बदल सकते हैंcontentType: 'application/x-www-form-urlencoded'


विचारों के लिए धन्यवाद। मैंने डेटाटाइप को सेट नहीं करने की कोशिश की, और इसे application/x-www-form-urlencodedऔर यहां तक ​​कि सेट कर दिया text/plain। और मैंने Access-Control-Allow-Methods "POST, GET, OPTIONS"कुछ भी काम नहीं किया का एक प्रतिक्रिया हैडर जोड़ने की कोशिश की ।
मैग्माटिक

क्या आप जावास्क्रिप्ट त्रुटि कंसोल (या फायरबग कंसोल) में देख सकते हैं और देख सकते हैं कि अनुरोध के दौरान कोई त्रुटि है या नहीं? इसके अलावा, यदि आप जानते हैं कि Wireshark का उपयोग कैसे किया जाता है, तो आप इसका उपयोग वास्तविक HTTP अनुरोधों को तार पर देखने के लिए कर सकते हैं।
मोनसुर

1
"एक अन्य संभावना यह है कि डेटा टाइप करना: json कारण JQuery को सामग्री-प्रकार: एप्लिकेशन / json हेडर भेजना है" - ऐसा नहीं होता है। अनुरोध हेडर को dataTypeप्रभावित करता है Acceptलेकिन अनुरोध हेडर को नहीं Content-Type
क्वेंटिन

9

आप js में "परम" भेज रहे हैं: request.send(params);

लेकिन "डेटा" jquery में "। क्या डेटा को परिभाषित किया गया है?" data:data,

इसके अलावा, आपके पास URL में एक त्रुटि है:

$.ajax( {url:url,
         type:"POST",
         dataType:"json",
         data:data, 
         success:function(data, textStatus, jqXHR) {alert("success");},
         error: function(jqXHR, textStatus, errorThrown) {alert("failure");}
});

आप $ .post के लिए एक के साथ वाक्यविन्यास मिश्रण कर रहे हैं


अद्यतन : मैं महाशय जवाब के आधार पर चारों ओर घूम रहा था, और मैंने पाया कि आपको जोड़ने की जरूरत है Access-Control-Allow-Headers: Content-Type(नीचे पूर्ण अनुच्छेद है)

http://metajack.im/2010/01/19/crossdomain-ajax-for-xmpp-http-binding-made-easy/

कोर कैसे काम करता है

CorS Flash की crossdomain.xml फ़ाइल के समान काम करता है। मूल रूप से, ब्राउज़र एक क्रॉस-डोमेन अनुरोध एक सेवा को भेजेगा, HTTP हेडर उत्पत्ति को अनुरोध करने वाले सर्वर पर सेट करेगा। सेवा में कुछ हेडर शामिल हैं जैसे कि एक्सेस-कंट्रोल-अनुमति-उत्पत्ति यह दर्शाने के लिए कि इस तरह के अनुरोध की अनुमति है या नहीं।

बीओएसएच कनेक्शन प्रबंधकों के लिए, यह निर्दिष्ट करने के लिए पर्याप्त है कि सभी मूल की अनुमति है, एक्सेस-कंट्रोल-अनुमति-उत्पत्ति के मूल्य को * पर सेट करके। एक्सेस-कंट्रोल-अनुमति-हेडर हेडर में कंटेंट-टाइप हेडर को भी व्हाइट-लिस्ट किया जाना चाहिए।

अंत में, बीओएसएच कनेक्शन प्रबंधक अनुरोधों सहित कुछ प्रकार के अनुरोधों के लिए, अनुमतियों की जांच पूर्व-उड़ान होगी। ब्राउज़र एक विकल्प का अनुरोध करेगा और कुछ HTTP हेडर को वापस पाने की उम्मीद करेगा जो इंगित करता है कि कौन से मूल की अनुमति है, कौन सी विधियों की अनुमति है, और यह प्राधिकरण कितने समय तक चलेगा। उदाहरण के लिए, पंजाब और पंजाब पैच मैंने विकल्प के लिए क्या किया है:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type 
Access-Control-Max-Age: 86400

1
माफ़ करना। हाँ। var data = {action:"something"}
मैग्माटिक

आप यहाँ दोनों कार्यों के लिए वाक्यविन्यास की तुलना कर सकते हैं: api.jquery.com/jQuery.post
Aleadam

मैं सिर्फ सेटिंग्स में यूआरएल के साथ यह कोशिश की, लेकिन एक ही समस्या है। .Ajax फ़ंक्शन इसे किसी भी तरह ले सकता है।
मैगमैटिक

मेरे पास पहले से ही दो हेडर थे। मैंने बाकी दोनों को जोड़ा। फिर भी jQuery के साथ "विफलता"। सादे जावास्क्रिप्ट अभी भी काम करता है।
मगमैटिक

अंत में मैं के बारे में सोच सकते हैं उपयोग करने के लिए है api.jquery.com/jQuery.ajaxSetup सेट करने के लिए jQuery.ajaxSetup({'beforeSend': function(xhr) {xhr.setRequestHeader(string, string)}})और खेलने के लिए अलग हेडर के साथ भेजा (यहां रेल के लिए एक उदाहरण: railscasts.com/episodes/136-jquery )
Aleadam

1

पोस्ट करने से पहले Cors अनुरोध विधि बदल देते हैं, विकल्प से, इसलिए, आपका पोस्ट डेटा नहीं भेजा जाएगा। जिस तरह से इस cors इशू को हैंडल करने के लिए काम किया गया है, वह ajax के साथ रिक्वेस्ट परफॉर्म कर रहा है, जो ऑप्शन्स मेथड को सपोर्ट नहीं करता है। उदाहरण कोड:

        $.ajax({
            type: "POST",
            crossdomain: true,
            url: "http://localhost:1415/anything",
            dataType: "json",
            data: JSON.stringify({
                anydata1: "any1",
                anydata2: "any2",
            }),
            success: function (result) {
                console.log(result)
            },
            error: function (xhr, status, err) {
                console.error(xhr, status, err);
            }
        });

सी # सर्वर पर इस हेडर के साथ:

                    if (request.HttpMethod == "OPTIONS")
                    {
                          response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With");
                          response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
                          response.AddHeader("Access-Control-Max-Age", "1728000");
                    }
                    response.AppendHeader("Access-Control-Allow-Origin", "*");

-2

निम्नलिखित तरीके से अपने Jquery को संशोधित करें:

$.ajax({
            url: someurl,
            contentType: 'application/json',
            data: JSONObject,
            headers: { 'Access-Control-Allow-Origin': '*' }, //add this line
            dataType: 'json',
            type: 'POST',                
            success: function (Data) {....}
});

मैं अपना अजाक्स कालस समकालिक क्यों बनाना चाहता हूँ !?
राडोको दिनेव

contentType: 'application/json', data: JSONObject,- सर्वर JSON की उम्मीद नहीं कर रहा है, इसलिए JSON भेजने से कोई मतलब नहीं होगा। इसके अलावा JSON ऑब्जेक्ट जैसी कोई चीज नहीं है
क्वेंटिन

1
headers: { 'Access-Control-Allow-Origin': '*' }, //add this line- ऐसा कभी न करें। Access-Control-Allow-Originएक प्रतिक्रिया हैडर है, अनुरोध हैडर नहीं है। सबसे अच्छा यह कुछ नहीं करेगा। कम से कम यह अनुरोध को एक साधारण अनुरोध से एक पूर्वनिर्धारित अनुरोध में परिवर्तित कर देगा जो सर्वर पर निपटने के लिए कठिन बना देता है।
क्वेंटिन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.