2008-09-16 14 views
115

से प्रगति कैसे प्राप्त करें क्या एक XMLHttpRequest (बाइट अपलोड किए गए बाइट डाउनलोड) की प्रगति प्राप्त करना संभव है?XMLHttpRequest

उपयोगकर्ता एक बड़ी फ़ाइल अपलोड करते समय प्रगति पट्टी दिखाने के लिए उपयोगी होगा। मानक एपीआई इसका समर्थन नहीं कर रहा है, लेकिन हो सकता है कि वहां मौजूद किसी भी ब्राउज़र में कुछ गैर-मानक एक्सटेंशन हो? यह सब के बाद एक सुंदर स्पष्ट सुविधा की तरह लगता है, क्योंकि ग्राहक जानता है कि कितने बाइट अपलोड/डाउनलोड किए गए थे।

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

http://ajaxpatterns.org/Progress_Indicator

सबसे होनहार दृष्टिकोण से एक एक दूसरे संचार चैनल सर्वर से वापस खोलने जा रहा है यह पूछते हैं कि के ज्यादा के लिए:

उत्तर

10

AJAX के पैटर्न यहाँ प्रगति संकेतक का एक अच्छा विचार-विमर्श नहीं है स्थानांतरण पूरा हो गया है।

+7

मुझे लगता है कि लिंक मृत –

2

यदि आपके पास अपने अपाचे तक पहुंच है और तीसरे पक्ष के कोड पर भरोसा है, तो आप apache upload progress module का उपयोग कर सकते हैं (यदि आप अपाचे का उपयोग करते हैं, तो nginx upload progress module भी है)।

अन्यथा, आपको एक स्क्रिप्ट लिखनी होगी जिसे आप फ़ाइल की स्थिति का अनुरोध करने के लिए बैंड से बाहर निकाल सकते हैं (उदाहरण के लिए tmp फ़ाइल के फाइलसाइज़ को जांचना)।

फ़ायरफ़ॉक्स 3 में कुछ काम चल रहा है, मुझे लगता है कि ब्राउज़र पर अपलोड प्रगति समर्थन जोड़ने के लिए, लेकिन यह सभी ब्राउज़रों में नहीं जा रहा है और थोड़ी देर के लिए व्यापक रूप से अपनाया जा सकता है (अधिक दयालुता)।

4

कुल अपलोड होने के लिए इसे संभालने का कोई तरीका प्रतीत नहीं होता है, लेकिन आप जो डाउनलोड करना चाहते हैं उसके समान कुछ है। एक बार तैयार चरण 3 है, तो आप समय-समय पर स्ट्रिंग के रूप में डाउनलोड की गई सभी सामग्री प्राप्त करने के लिए प्रतिक्रिया से पूछ सकते हैं (यह आईई में काम नहीं करता है), जब तक कि यह सब उपलब्ध न हो, उस बिंदु पर यह तैयार हो जाएगा 4. कुल किसी भी समय डाउनलोड किए गए बाइट्स प्रतिक्रिया पाठ में संग्रहीत स्ट्रिंग में कुल बाइट्स के बराबर होंगे।

अपलोड प्रश्न के लिए सभी या कुछ भी नहीं पहुंचने के लिए, क्योंकि आपको अपलोड करने के लिए एक स्ट्रिंग पास करनी है (और इसके कुल बाइट्स को निर्धारित करना संभव है) तैयार चरण 0 और 1 के लिए भेजे गए कुल बाइट 0 होंगे, और तैयार चरण 2 के लिए कुल आपके द्वारा पारित स्ट्रिंग में कुल बाइट होंगे। तैयार 3 और 4 में भेजे गए और प्राप्त किए गए कुल बाइट मूल स्ट्रिंग में बाइट्स और प्रतिक्रिया टेक्स्ट में कुल बाइट्स का योग होगा।

-6

शुद्ध जावास्क्रिप्ट के साथ ऐसा करने का एकमात्र तरीका कुछ प्रकार के मतदान तंत्र को लागू करना है। सर्वर द्वारा प्राप्त बाइट्स की संख्या प्राप्त करने के लिए आपको निश्चित अंतराल (उदाहरण के लिए प्रत्येक 5 सेकंड) पर AJAX अनुरोधों को भेजने की आवश्यकता होगी।

फ़्लैश का उपयोग करने का एक और अधिक प्रभावी तरीका होगा। फ्लेक्स घटक FileReference समय-समय पर अपलोड किए गए बाइट्स की संख्या वाले 'प्रगति' ईवेंट को प्रेषित करता है। यदि आपको जावास्क्रिप्ट से चिपकने की आवश्यकता है, तो पुल क्रियालेख और जावास्क्रिप्ट के बीच उपलब्ध हैं। अच्छी खबर यह है कि यह काम पहले से ही किया गया है आप :)

swfupload

के लिए इस पुस्तकालय फ़्लैश प्रगति घटना पर एक जावास्क्रिप्ट हैंडलर रजिस्टर करने के लिए अनुमति देता है।

इस समाधान में सर्वर पक्ष पर अतिरिक्त संसाधनों की आवश्यकता नहीं है।

122

बाइट अपलोड करने के लिए यह काफी आसान है। बस xhr.upload.onprogress घटना की निगरानी करें। ब्राउज़र उन फ़ाइलों के आकार को जानता है जिन्हें अपलोड करना है और अपलोड किए गए डेटा का आकार, ताकि यह प्रगति जानकारी प्रदान कर सके।

बाइट डाउनलोड करने के लिए (xhr.responseText के साथ जानकारी प्राप्त करते समय), यह थोड़ा और मुश्किल है, क्योंकि ब्राउज़र नहीं जानता कि सर्वर अनुरोध में कितने बाइट भेजे जाएंगे। इस मामले में ब्राउजर जानता है कि एकमात्र चीज बाइट्स का आकार प्राप्त कर रही है।

इसके लिए एक समाधान है, सर्वर स्क्रिप्ट पर Content-Length शीर्षलेख सेट करने के लिए पर्याप्त है, ताकि ब्राउजर को प्राप्त होने वाले बाइट्स का कुल आकार प्राप्त हो सके।

अधिक के लिए https://developer.mozilla.org/en/Using_XMLHttpRequest पर जाएं।

उदाहरण: मेरे सर्वर स्क्रिप्ट एक ज़िप फ़ाइल पढ़ता है (यह 5 सेकंड लगते हैं):

$filesize=filesize('test.zip'); 

header("Content-Length: " . $filesize); // set header length 
// if the headers is not set then the evt.loaded will be 0 
readfile('test.zip'); 
exit 0; 

अब मैं, सर्वर स्क्रिप्ट के डाउनलोड की प्रक्रिया की निगरानी कर सकते क्योंकि मैं जानता हूँ कि यह कुल लंबाई है:

function updateProgress(evt) 
{ 
    if (evt.lengthComputable) 
    { // evt.loaded the bytes the browser received 
     // evt.total the total bytes set by the header 
     // jQuery UI progress bar to show the progress on screen 
    var percentComplete = (evt.loaded/evt.total) * 100; 
    $('#progressbar').progressbar("option", "value", percentComplete); 
    } 
} 
function sendreq(evt) 
{ 
    var req = new XMLHttpRequest(); 
    $('#progressbar').progressbar();  
    req.onprogress = updateProgress; 
    req.open('GET', 'test.php', true); 
    req.onreadystatechange = function (aEvt) { 
     if (req.readyState == 4) 
     { 
      //run any callback here 
     } 
    }; 
    req.send(); 
} 
+24

टिप्पण लायक, "सामग्री-लंबाई" है नहीं एक अनुमान के अनुसार लंबाई, यह सही हो गया है हो सकता है लम्बाई, बहुत छोटा और ब्राउज़र डाउनलोड को काट देगा, बहुत लंबा होगा और ब्राउजर यह मान लेगा कि डाउनलोड पूरा होने में असफल रहा। –

+1

हाँ सही, अनुमानित गलत है, बस एक भ्रम – albanx

+0

@ChrisChilvers इसका मतलब है कि एक PHP फ़ाइल सही ढंग से गणना नहीं की जा सकती है, है ना? – Hydro

2

<!DOCTYPE html> 
 
<html> 
 
<body> 
 
<p id="demo">result</p> 
 
<button type="button" onclick="get_post_ajax();">Change Content</button> 
 
<script type="text/javascript"> 
 
\t function update_progress(e) 
 
\t { 
 
\t if (e.lengthComputable) 
 
\t { 
 
\t  var percentage = Math.round((e.loaded/e.total)*100); 
 
\t  console.log("percent " + percentage + '%'); 
 
\t } 
 
\t else 
 
\t { 
 
\t \t console.log("Unable to compute progress information since the total size is unknown"); 
 
\t } 
 
\t } 
 
\t function transfer_complete(e){console.log("The transfer is complete.");} 
 
\t function transfer_failed(e){console.log("An error occurred while transferring the file.");} 
 
\t function transfer_canceled(e){console.log("The transfer has been canceled by the user.");} 
 
\t function get_post_ajax() 
 
\t { 
 
\t \t var xhttp; 
 
\t \t if (window.XMLHttpRequest){xhttp = new XMLHttpRequest();}//code for modern browsers} 
 
\t \t else{xhttp = new ActiveXObject("Microsoft.XMLHTTP");}// code for IE6, IE5 \t \t 
 
\t \t xhttp.onprogress = update_progress; 
 
\t \t xhttp.addEventListener("load", transfer_complete, false); 
 
\t \t xhttp.addEventListener("error", transfer_failed, false); 
 
\t \t xhttp.addEventListener("abort", transfer_canceled, false); \t \t 
 
\t \t xhttp.onreadystatechange = function() 
 
\t \t { 
 
\t  \t if (xhttp.readyState == 4 && xhttp.status == 200) 
 
\t  \t { 
 
\t  \t \t document.getElementById("demo").innerHTML = xhttp.responseText; 
 
\t  \t } 
 
\t \t }; 
 
\t xhttp.open("GET", "http://it-tu.com/ajax_test.php", true); 
 
\t xhttp.send(); 
 
\t } 
 
</script> 
 
</body> 
 
</html>

Result