jQuery के अजाक्स (jsonp) एक टाइमआउट को अनदेखा करता है और त्रुटि ईवेंट को आग नहीं देता है


89

कुछ बुनियादी त्रुटि हैंडलिंग को जोड़ने के लिए, मैं कोड के एक टुकड़े को फिर से लिखना चाहता था जो कि कुछ फोटो में फ़्लिकर से खींचने के लिए jQuery के $ .getJSON का उपयोग करता था। ऐसा करने का कारण यह है कि $ .getJSON एरर हैंडलिंग या टाइमआउट के साथ काम नहीं करता है।

चूँकि $ .getJSON, $ .ajax के आसपास एक आवरण मात्र है। मैंने बात फिर से लिखने और आश्चर्य चकित करने का निर्णय लिया, यह त्रुटिपूर्ण काम करता है।

हालांकि अब मज़ा शुरू होता है। जब मैं जान-बूझकर 404 (URL को बदलकर) या नेटवर्क को टाइमआउट (इंटरव्यू तक हुक नहीं होने के कारण) का कारण बनता हूं, तो त्रुटि की घटना में आग नहीं लगती है। मैं एक नुकसान में हूं कि मैं क्या गलत कर रहा हूं। मदद काफी सराहना की है।

यहाँ कोड है:

$(document).ready(function(){

    // var jsonFeed = "http://api.flickr.com/services/feeds/photos_public.gne"; // correct URL
    var jsonFeed = "http://api.flickr.com/services/feeds/photos_public.gne_______"; // this should throw a 404

    $.ajax({
        url: jsonFeed,
        data: { "lang" : "en-us",
                "format" : "json",
                "tags" : "sunset"
        },
        dataType: "jsonp",
        jsonp: "jsoncallback",
        timeout: 5000,
        success: function(data, status){
            $.each(data.items, function(i,item){
                $("<img>").attr("src", (item.media.m).replace("_m.","_s."))
                          .attr("alt", item.title)
                          .appendTo("ul#flickr")
                          .wrap("<li><a href=\"" + item.link + "\"></a></li>");
                if (i == 9) return false;
            });
        },
        error: function(XHR, textStatus, errorThrown){
            alert("ERREUR: " + textStatus);
            alert("ERREUR: " + errorThrown);
        }
    });

});

मैं यह जोड़ना चाहूंगा कि जब jQuery संस्करण 1.4.2 पर था, तो यह प्रश्न पूछा गया था

जवाबों:


86

JSONP अनुरोधों के साथ त्रुटि से निपटने के लिए jQuery 1.5 और उच्चतर का बेहतर समर्थन है। हालांकि, आपको $.ajaxइसके बजाय विधि का उपयोग करने की आवश्यकता है $.getJSON। मेरे लिए, यह काम करता है:

var req = $.ajax({
    url : url,
    dataType : "jsonp",
    timeout : 10000
});

req.success(function() {
    console.log('Yes! Success!');
});

req.error(function() {
    console.log('Oh noes!');
});

टाइमआउट लगता है कि ट्रिक करें और त्रुटि हैंडलर को कॉल करें, जब 10 सेकंड के बाद कोई सफल अनुरोध न हो।

मैंने इस विषय पर थोड़ा ब्लॉगपोस्ट भी किया।


23
मैं अभी इस बात से नाराज़ हूं कि मैंने 2 दिनों के लिए इस समस्या के खिलाफ सिर उठाया है और स्टैकऑवरफ़्लो पर कुछ अस्पष्ट खोज लेता है यह पता लगाने के लिए कि मुझे आग लगाने के लिए क्रॉस-डोमेन अनुरोध में टाइमआउट जोड़ना होगा। यह jQuery प्रलेखन में कैसे उल्लेख नहीं किया जा सकता है? क्या क्रॉस-डोमेन जसनप अनुरोध वास्तव में असामान्य है? किसी भी मामले में, धन्यवाद, धन्यवाद, धन्यवाद। +1
chrixian

इस समाधान के साथ मैं स्थिति कोड प्राप्त नहीं कर सकता, मुझे इसके बजाय "टाइमआउट" मिलता है। इसलिए मुझे नहीं पता कि वास्तविक त्रुटि क्या है, और यह संपत्ति को संभाल नहीं सकता है।
टैरलॉग

10
@ टैरलॉग: यह तर्कसंगत है। JSONP अनुरोध देशी Ajax अनुरोध नहीं हैं, वे बस जावास्क्रिप्ट <script>टैग हैं जिन्हें गतिशील रूप से डाला जाता है। केवल एक चीज जिसे आप जान सकते हैं, वह यह है कि अनुरोध विफल रहा, न कि स्थिति कोड क्या था। यदि आप स्टेटस कोड प्राप्त करना चाहते हैं तो आपको पारंपरिक अजाक्स अनुरोध या अन्य क्रॉस-डोमेन तकनीकों का उपयोग करना होगा।
कर्क राशि

1
जैसा कि @Husky ने कहा, आपके पास JSONP के साथ स्थिति कोड नहीं हो सकते हैं, और मेरा मानना ​​है कि इसीलिए आपको इससे बचने की कोशिश करनी चाहिए। त्रुटि प्राप्त करने का एकमात्र तरीका टाइमआउट है। इसे jQuery प्रलेखन (कई अन्य चीजों के रूप में) में बेहतर तरीके से समझाया जाना चाहिए।
एलेजांद्रो गार्सिया इग्लेसियस

67

यह jQuery में मूल jsonp कार्यान्वयन के साथ एक ज्ञात सीमा है। नीचे दिया गया पाठ IBM DeveloperWorks का है

JSONP मैशअप के निर्माण के लिए एक बहुत शक्तिशाली तकनीक है, लेकिन, दुर्भाग्य से, यह आपके सभी क्रॉस-डोमेन संचार आवश्यकताओं के लिए इलाज नहीं है। इसमें कुछ कमियां हैं जिन्हें विकास संसाधनों को पूरा करने से पहले गंभीरता से विचार करना चाहिए। सबसे पहले और सबसे महत्वपूर्ण, JSONP कॉल के लिए कोई त्रुटि हैंडलिंग नहीं है। यदि गतिशील स्क्रिप्ट सम्मिलन काम करता है, तो आपको कॉल किया जाता है; यदि नहीं, तो कुछ नहीं होता है। यह बस चुपचाप विफल रहता है। उदाहरण के लिए, आप सर्वर से 404 त्रुटि को पकड़ने में सक्षम नहीं हैं। न ही आप अनुरोध को रद्द या पुनः आरंभ कर सकते हैं। हालाँकि, आप समय की उचित मात्रा के इंतजार के बाद समय समाप्त कर सकते हैं। (भविष्य के jQuery के संस्करणों में JSONP अनुरोधों के लिए एक गर्भपात सुविधा हो सकती है।)

हालाँकि GoogleCode पर एक jsonp प्लग-इन उपलब्ध है जो त्रुटि से निपटने के लिए सहायता प्रदान करता है। आरंभ करने के लिए, बस अपने कोड में निम्नलिखित बदलाव करें।

आप इसे डाउनलोड कर सकते हैं, या प्लग-इन में केवल एक स्क्रिप्ट संदर्भ जोड़ सकते हैं।

<script type="text/javascript" 
     src="http://jquery-jsonp.googlecode.com/files/jquery.jsonp-1.0.4.min.js">
</script>

फिर नीचे दिखाए गए अनुसार अपने ajax कॉल को संशोधित करें:

$(function(){
    //var jsonFeed = "http://api.flickr.com/services/feeds/photos_public.gne"; // correct URL
    var jsonFeed = "http://api.flickr.com/services/feeds/photos_public.gne_______"; // this should throw a 404  
    $.jsonp({
        url: jsonFeed,
        data: { "lang" : "en-us",
                "format" : "json",
                "tags" : "sunset"
        },
        dataType: "jsonp",
        callbackParameter: "jsoncallback",
        timeout: 5000,
        success: function(data, status){
            $.each(data.items, function(i,item){
                $("<img>").attr("src", (item.media.m).replace("_m.","_s."))
                          .attr("alt", item.title)
                          .appendTo("ul#flickr")
                          .wrap("<li><a href=\"" + item.link + "\"></a></li>");
                if (i == 9) return false;
            });
        },
        error: function(XHR, textStatus, errorThrown){
            alert("ERREUR: " + textStatus);
            alert("ERREUR: " + errorThrown);
        }
    });
});

आप जवाब के लिए धन्यवाद जोस! JQuery में देशी jsonp के सीमित कार्यान्वयन का कारण था कि मैं इसके बजाय $ .ajax के लिए गया था। हालाँकि, ऐसा लगता है कि समस्या यह नहीं है कि $। क्या वो सही है?
मतिज

आज तक समय नहीं था। हालांकि यह काम नहीं करता है। मुझे एक त्रुटि मिल रही है, लेकिन इसके बारे में है। मुझे नहीं पता कि एरर के रूप में क्या त्रुटि अपरिभाषित है। अभी के लिए मैं $ .ajax और त्रुटि संदेशों की कमी के साथ रहूँगा। जावास्क्रिप्ट मेरे लिए वेबपेज के शीर्ष पर एक अतिरिक्त परत है। यदि फ़्लिकर नीचे है या त्रुटि संदेश फेंक रहा है, तो हमें अभी इसके लिए रहना होगा :) आपके सुझाव के लिए धन्यवाद।
मैटिज

तो मूल रूप से जोस के सुझाव को jsonp plugin का उपयोग करना चाहिए, यदि सही तरीके से किया गया है, तो काम करना चाहिए। हालाँकि अभी के लिए मैं jQuery के लिए बेसिक जॅसन रैपर के साथ रहूँगा।
मैटिज्स

यह मेरे लिए शानदार ढंग से काम करता है, जब मैंने दीवार को जन्सप की त्रुटि से निपटने की अंतर्निहित सीमाओं के साथ मारा था
जेरेमी फ्रे

7
इस टिप द्वारा एक और डेवलपर को बचाया गया। धन्यवाद!
chesterbr

12

एक समाधान यदि आप jQuery 1.4 के साथ फंस गए हैं:

var timeout = 10000;
var id = setTimeout( errorCallback, timeout );
$.ajax({
    dataType: 'jsonp',
    success: function() {
        clearTimeout(id);
        ...
    }
});

2
सिर्फ एक टिप्पणी, इसका 1.4 के साथ अटक गए लोगों के लिए एक वैध समाधान है, लेकिन अपने टाइमआउट चर को पर्याप्त रूप से सेट करें, ताकि आपको धीमी webservices के साथ समस्या न हो :)। यदि आप इसे उदाहरण के लिए एक सेकंड के लिए सेट करते हैं, तो आप देख सकते हैं कि मेरा क्या मतलब है, त्रुटि कॉलबैक ट्रिगर हो जाता है, जबकि 1 सेकंड के बाद भी आपका कॉल अभी भी प्राप्त होता है और सफलता फ़ंक्शन को कॉल करता है। तो बस ध्यान रखें कि इसे यथोचित रूप से पर्याप्त रूप से सेट किया जाए
सैंडर

@ यदि आप 10 सेकंड के बाद 5 सेकंड के टाइमआउट के बाद उत्तर प्राप्त कर लेते हैं, तो सफलता फ़ंक्शन को भी बुलाया जा सकता है। .abort()समयावधि के बाद लंबित jqXHR पर कॉल करना बेहतर तरीका हो सकता है।
मटीज

8

यह jQuery की "ज्ञात" सीमा हो सकती है; हालाँकि, यह अच्छी तरह से प्रलेखित नहीं लगता है। मैंने आज लगभग 4 घंटे बिताए, यह समझने की कोशिश कर रहा था कि मेरा टाइमआउट काम क्यों नहीं कर रहा था।

मैंने jquery.jsonp पर स्विच किया और यह काम एक आकर्षण पसंद आया। धन्यवाद।


2

JQuery 1.5 के रूप में हल किया जा करने के लिए लगता है। मैंने ऊपर कोड की कोशिश की है और मुझे कॉलबैक मिल गया है।

मैं कहता हूं "प्रतीत होता है" क्योंकि jQuery.ajax () के लिए त्रुटि कॉलबैक के प्रलेखन में अभी भी निम्नलिखित नोट हैं:

नोट: इस हैंडलर को क्रॉस-डोमेन स्क्रिप्ट और JSONP अनुरोधों के लिए नहीं कहा जाता है।


1

जोस बेसिलियो के जवाब में उल्लिखित jquery-jsonp jQuery प्लगइन अब GitHub पर पाया जा सकता है

दुर्भाग्य से प्रलेखन कुछ संयमी है, इसलिए मैंने एक सरल उदाहरण प्रदान किया है:

    $.jsonp({
        cache: false,
        url: "url",
        callbackParameter: "callback",
        data: { "key" : "value" },
        success: function (json, textStatus, xOptions) {
            // handle success - textStatus is "success"   
        },
        error: function (xOptions, textStatus) {
            // handle failure - textStatus is either "error" or "timeout"
        }
    });

महत्वपूर्ण कॉलबैकपैरमीटर को कॉल $ .jsonp () में शामिल करें अन्यथा मैंने पाया है कि कॉलबैक फ़ंक्शन को कभी भी सर्विस कॉल के क्वेरी स्ट्रिंग में इंजेक्ट नहीं किया जाता है (वर्तमान में jquery-jsonp के संस्करण 2.4.0 के रूप में)।

मुझे पता है कि यह सवाल पुराना है, लेकिन JSONP का उपयोग करते हुए त्रुटि से निपटने का मुद्दा अभी भी 'हल नहीं हुआ है।' उम्मीद है कि यह अपडेट दूसरों की सहायता करेगा क्योंकि यह प्रश्न "jquery jsonp एरर हैंडलिंग" के लिए Google के भीतर शीर्ष पर है।


अच्छा लगता है, और अद्भुत है कि यह धागा तीन साल बाद भी जीवित है ...
Matijs

1

स्क्रिप्ट की ऑनरोर घटना को सुनने के बारे में क्या? मुझे यह समस्या थी और इसे jquery की विधि को पैच करके हल किया जहां स्क्रिप्ट टैग बनाया गया था। यहाँ कोड का दिलचस्प सा है:

// Attach handlers for all browsers
script.onload = script.onreadystatechange = function( _, isAbort ) {

    if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {

        cleanup();

        // Callback if not abort
        if ( !isAbort ) {
            callback( 200, "success" );
        }
    }
};

/* ajax patch : */
script.onerror = function(){
    cleanup();

    // Sends an inappropriate error, still better than nothing
    callback(404, "not found");
};

function cleanup(){
    // Handle memory leak in IE
    script.onload = script.onreadystatechange = null;

    // Remove the script
    if ( head && script.parentNode ) {
        head.removeChild( script );
    }

    // Dereference the script
    script = undefined;
}

आप इस समाधान के बारे में क्या सोचते हैं? क्या यह संगतता मुद्दों के कारण होने की संभावना है?

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.