javascript-events - jQuery AJAX स्ट्रीम incrementally पढ़ा?




long-polling http-streaming (5)

JQuery का उपयोग करके इसे प्राप्त करने का एक सीधा तरीका यहां है (जैसा ओपी द्वारा अनुरोध किया गया है):

सबसे पहले, https://gist.github.com/chrishow/3023092 (इस प्रतिक्रिया के निचले हिस्से में संलग्न) से नीचे दिए गए कोड को चलाकर ऑनएस्टस्टेटchange का समर्थन करने के लिए AJAX ऑब्जेक्ट का विस्तार करें। फिर केवल एक ऑनएक्सस्टेटेन्चेंज फ़ंक्शन का उपयोग करके AJAX को कॉल करें जो नए टेक्स्ट के लिए xhr.responseText की जांच करेगा।

यदि आप फैनसीयर भी प्राप्त करना चाहते हैं, तो आप प्रत्येक बार जब इसे पढ़ते हैं, तो प्रतिक्रिया डेटा को साफ़ कर सकते हैं, जैसे कि here वर्णित)।

उदाहरण के लिए, https://jsfiddle.net/g1jmwcmw/1/ , जो https://code.jquery.com/jquery-1.5.js से प्रतिक्रिया डाउनलोड करेगा और इसे आपके कंसोल विंडो के अंदर हिस्सों में आउटपुट करेगा, इसका उपयोग करके नीचे कोड (जिसे आप सिर्फ एक HTML पृष्ठ में कॉपी कर सकते हैं और फिर अपने ब्राउज़र में खोल सकते हैं):

<!-- jquery >= 1.5. maybe earlier too but not sure -->
<script src=https://code.jquery.com/jquery-1.5.min.js></script>
<script>
/* One-time setup (run once before other code)
 *   adds onreadystatechange to $.ajax options
 *   from https://gist.github.com/chrishow/3023092)
 *   success etc will still fire if provided
 */
$.ajaxPrefilter(function( options, originalOptions, jqXHR ) {
    if ( options.onreadystatechange ) {
        var xhrFactory = options.xhr;
        options.xhr = function() {
            var xhr = xhrFactory.apply( this, arguments );
            function handler() {
                options.onreadystatechange( xhr, jqXHR );
            }
            if ( xhr.addEventListener ) {
                xhr.addEventListener( "readystatechange", handler, false );
            } else {
                setTimeout( function() {
                    var internal = xhr.onreadystatechange;
                    if ( internal ) {
                        xhr.onreadystatechange = function() {
                            handler();
                            internal.apply( this, arguments ); 
                        };
                    }
                }, 0 );
            }
            return xhr;
        };
    }
});

// ----- myReadyStateChange(): this will do my incremental processing -----
var last_start = 0; // using global var for over-simplified example
function myReadyStateChange(xhr /*, jqxhr */) {
    if(xhr.readyState >= 3 && xhr.responseText.length > last_start) {
        var chunk = xhr.responseText.slice(last_start);
        alert('Got chunk: ' + chunk);
        console.log('Got chunk: ', chunk);
        last_start += chunk.length;
    }
}

// ----- call my url and process response incrementally -----
last_start = 0;
$.ajax({
  url: "https://code.jquery.com/jquery-1.5.js", // whatever your target url is goes here
  onreadystatechange: myReadyStateChange
});

</script>

मैंने इस सवाल को पढ़ा है लेकिन यह मेरे प्रश्न का बिल्कुल जवाब नहीं देता है। दुर्भाग्यवश, ऐसा लगता है कि एक्सएचआर ऑब्जेक्ट में चीजें बदल गई हैं क्योंकि मैंने आखिरकार AJAX को देखा था, इसलिए पॉप्युलेट होने से पहले responseText को सीधे एक्सेस करना संभव नहीं है।

मुझे एक ऐसा पृष्ठ लिखना है जो AJAX का उपयोग करता है (अधिमानतः jQuery, लेकिन मैं सुझावों के लिए खुला हूं) सर्वर से HTTP के माध्यम से सीएसवी डेटा पुनर्प्राप्त करने के लिए मेरा कोई नियंत्रण नहीं है। प्रतिक्रिया डेटा काफी बड़ा हो सकता है; पाठ का एक मेगाबाइट असामान्य नहीं है।

सर्वर स्ट्रीम-फ्रेंडली है। डेटा की स्ट्रीम तक पहुंच प्राप्त करने के लिए अभी भी कोई तरीका है क्योंकि इसे वापस किया जा रहा है, सीधे जावास्क्रिप्ट से?

मेरे पास कुछ PHP कोड लिखने का विकल्प है जो मध्य में रहता है और कुछ प्रकार के "धूमकेतु" तकनीक (लंबे मतदान, इवेंटसोर्स इत्यादि) का उपयोग करता है, लेकिन यदि संभव हो तो मैं इससे बचना पसंद करूंगा।

यदि यह प्रासंगिक है, तो इस प्रश्न के लिए मान लें कि उपयोगकर्ताओं के पास फ़ायरफ़ॉक्स / क्रोम / ओपेरा का नवीनतम संस्करण है और पुरानी ब्राउज़र संगतता कोई समस्या नहीं है।


टेक्स्ट या एचटीएमएल आउटपुट करते समय यह काफी सरल है। नीचे एक उदाहरण है।

(यदि आप JSON आउटपुट करने का प्रयास करते हैं तो आप समस्याओं में भाग लेंगे, हालांकि मैं आगे से निपटूंगा।)

PHP फ़ाइल

header('Content-type: text/html; charset=utf-8');
function output($val)
{
    echo $val;
    flush();
    ob_flush();
    usleep(500000);
}
output('Begin... (counting to 10)');
for( $i = 0 ; $i < 10 ; $i++ )
{
    output($i+1);
}
output('End...');

एचटीएमएल फ़ाइल

<!DOCTYPE>
<html>
    <head>
        <title>Flushed ajax test</title>
        <meta charset="UTF-8" />
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    </head>
    <body>
        <script type="text/javascript">
        var last_response_len = false;
        $.ajax('./flushed-ajax.php', {
            xhrFields: {
                onprogress: function(e)
                {
                    var this_response, response = e.currentTarget.response;
                    if(last_response_len === false)
                    {
                        this_response = response;
                        last_response_len = response.length;
                    }
                    else
                    {
                        this_response = response.substring(last_response_len);
                        last_response_len = response.length;
                    }
                    console.log(this_response);
                }
            }
        })
        .done(function(data)
        {
            console.log('Complete response = ' + data);
        })
        .fail(function(data)
        {
            console.log('Error: ', data);
        });
        console.log('Request Sent');
        </script>
    </body>
</html>

अगर मुझे JSON के साथ ऐसा करने की ज़रूरत है तो क्या होगा?

वास्तव में एक एकल JSON ऑब्जेक्ट को लोड करना संभव नहीं है (इसे पूरी तरह लोड होने से पहले) क्योंकि जब तक आपके पास पूर्ण ऑब्जेक्ट नहीं है, तो वाक्यविन्यास हमेशा अमान्य होगा।

लेकिन अगर आपकी प्रतिक्रिया में कई JSON ऑब्जेक्ट्स हैं, तो एक दूसरे के बाद, तो एक बार में लोड करना संभव है, क्योंकि वे पाइप नीचे आते हैं।

तो मैंने ऊपर अपना कोड tweaked ...

  1. echo $val; से PHP फ़ाइल लाइन 4 बदलना echo $val; echo '{"name":"'.$val.'"};' । यह JSON ऑब्जेक्ट्स की एक श्रृंखला आउटपुट करता है।

  2. console.log(this_response); से एचटीएमएल फ़ाइल लाइन 24 बदलना console.log(this_response); सेवा मेरे

    this_response = JSON.parse(this_response);
    console.log(this_response.name);
    

    ध्यान दें कि यह प्राथमिक कोड मानता है कि ब्राउज़र में आने वाले प्रत्येक "खंड" वैध JSON ऑब्जेक्ट है। यह हमेशा ऐसा नहीं होगा क्योंकि आप भविष्यवाणी नहीं कर सकते कि पैकेट कैसे पहुंचेंगे - आपको अर्ध-कॉलन (या किसी अन्य विभाजक चरित्र के साथ आना) के आधार पर स्ट्रिंग को विभाजित करने की आवश्यकता हो सकती है।

application/json प्रयोग न करें

अपने हेडर को application/json बदलने के लिए मत - मैंने यह किया और यह मुझे 3 दिनों के लिए गुगलिंग कर रहा था। जब प्रतिक्रिया प्रकार application/json , तो ब्राउज़र पूरी तरह से पूरा होने तक प्रतिक्रिया पूरी होने तक प्रतीक्षा करता है। फिर पूर्ण प्रतिक्रिया को जांचने के लिए पार्स किया जाता है कि यह वास्तव में JSON है या नहीं। हालांकि हमारी पूर्ण प्रतिक्रिया {...};{...};{...}; जो वैध JSON नहीं है। jqXHR.done विधि मानती है कि एक त्रुटि हुई थी, क्योंकि पूर्ण प्रतिक्रिया JSON के रूप में पार्स नहीं की जा सकती है।

जैसा कि टिप्पणियों में बताया गया है, आप क्लाइंट पक्ष पर इस चेक को अक्षम कर अक्षम कर सकते हैं:

$.ajax(..., {dataType: "text"})

आशा है कि कुछ लोगों को यह उपयोगी लगेगा।


आप इसके लिए सीधे जावास्क्रिप्ट का उपयोग करना चाहते हैं। कारण यह है कि आप निरंतर मतदान करना चाहते हैं और कॉलबैक को आग लगने की प्रतीक्षा नहीं कर रहे हैं। इसके लिए आपको jQuery की आवश्यकता नहीं है, यह बहुत आसान है। उनके पास अजाक्स पैटर्न वेबसाइट पर इसके लिए कुछ अच्छा स्रोत कोड है

अनिवार्य रूप से, आप प्रतिक्रिया में अपनी आखिरी स्थिति का ट्रैक रखना चाहेंगे और समय-समय पर उस स्थान के पिछले पाठ के लिए मतदान करना चाहते हैं। आपके मामले में अंतर यह है कि आप पूरी घटना की सदस्यता ले सकते हैं और अपने मतदान को रोक सकते हैं।


चूंकि आप कहते हैं कि आपका सर्वर स्ट्रीम अनुकूल है (एसिंक्रोनस) और एक jquery समाधान की तलाश में था, क्या आपने jQuery स्ट्रीम प्लगइन की जांच की है ?

यह उपयोग करना वास्तव में आसान है और आपको वास्तव में कुछ भी ज्यादा चिंता करने की अनुमति नहीं देता है। इसमें बहुत अच्छा documentation भी है।


इंपीरेटिव → घोषणात्मक

JQuery में, चयनकर्ताओं का उपयोग DOM तत्वों को खोजने के लिए किया जाता है और फिर उन्हें ईवेंट हैंडलर को बाध्य / पंजीकृत करते हैं। जब कोई ईवेंट ट्रिगर होता है, तो वह (अनिवार्य) कोड DOM को अद्यतन / बदलने के लिए निष्पादित करता है।

AngularJS में, आप डीओएम तत्वों के बजाय विचारों के बारे में सोचना चाहते हैं। दृश्य (घोषणात्मक) HTML हैं जिसमें AngularJS निर्देश शामिल हैं। निर्देशों ने हमारे लिए दृश्यों के पीछे इवेंट हैंडलर स्थापित किए हैं और हमें गतिशील डाटाबेसिंग प्रदान करते हैं। चयनकर्ताओं का शायद ही कभी उपयोग किया जाता है, इसलिए आईडी (और कुछ प्रकार के वर्ग) की आवश्यकता बहुत कम हो जाती है। दृश्य मॉडल (स्कोप्स के माध्यम से) से बंधे हैं। दृश्य मॉडल का प्रक्षेपण है। घटनाक्रम मॉडल (यानी, डेटा, स्कोप गुण) बदलते हैं, और उन मॉडलों को प्रोजेक्ट करने वाले विचार "स्वचालित रूप से" अपडेट होते हैं।

AngularJS में, अपने डेटा को रखने वाले jQuery-चयनित DOM तत्वों की बजाय मॉडल के बारे में सोचें। उपयोगकर्ता द्वारा देखे जाने वाले कार्यों में हेरफेर करने के लिए कॉलबैक पंजीकृत करने के बजाय, उन मॉडलों के अनुमानों के रूप में विचारों के बारे में सोचें।

चिंताओ का विभाजन

jQuery अविभाज्य जावास्क्रिप्ट - व्यवहार (जावास्क्रिप्ट) संरचना (एचटीएमएल) से अलग है।

एंगुलरजेएस दृश्य / संरचना (एचटीएमएल) से व्यवहार को हटाने के लिए नियंत्रकों और निर्देशों का उपयोग करता है (जिनमें से प्रत्येक का अपना नियंत्रक हो सकता है, और / या संकलित और कार्यों को जोड़ना)। कोणीय में आपके आवेदन को अलग / व्यवस्थित करने में सहायता के लिए सेवाएं और फ़िल्टर भी हैं।

https://.com/a/14346528/215945 भी https://.com/a/14346528/215945

आवेदन डिजाइन

एक AngularJS आवेदन डिजाइन करने के लिए एक दृष्टिकोण:

  1. अपने मॉडल के बारे में सोचो। उन मॉडलों के लिए सेवाएं या अपनी खुद की जावास्क्रिप्ट ऑब्जेक्ट बनाएं।
  2. इस बारे में सोचें कि आप अपने मॉडल कैसे पेश करना चाहते हैं - आपके विचार। डायनामिक डाटाबेसिंग प्राप्त करने के लिए आवश्यक निर्देशों का उपयोग करके, प्रत्येक दृश्य के लिए HTML टेम्पलेट बनाएं।
  3. प्रत्येक दृश्य में नियंत्रक संलग्न करें (एनजी-व्यू और रूटिंग, या एनजी-कंट्रोलर का उपयोग करके)। नियंत्रक को केवल उस मॉडल डेटा को ढूंढें / प्राप्त करें जिसे दृश्य को अपना काम करने की आवश्यकता है। जितना संभव हो उतना पतला नियंत्रक बनाओ।

प्रोटोटाइप विरासत

जावास्क्रिप्ट प्रोटोटाइप विरासत कैसे काम करता है इस बारे में जानने के बिना आप jQuery के साथ बहुत कुछ कर सकते हैं। AngularJS अनुप्रयोगों को विकसित करते समय, यदि आप जावास्क्रिप्ट विरासत की अच्छी समझ रखते हैं तो आप कुछ सामान्य नुकसान से बचेंगे। अनुशंसित पढ़ने: AngularJS में स्कोप प्रोटोटाइप / प्रोटोटाइपिकल विरासत की बारीकियों क्या हैं?





jquery ajax javascript-events long-polling http-streaming