it-swarm-id.com

Cara mendapatkan kemajuan dari XMLHttpRequest

Apakah mungkin untuk mendapatkan kemajuan XMLHttpRequest (byte diunggah, byte diunduh)?

Ini akan berguna untuk menampilkan bilah kemajuan saat pengguna mengunggah file besar. API standar tampaknya tidak mendukungnya, tetapi mungkin ada beberapa ekstensi non-standar di salah satu browser di luar sana? Sepertinya fitur yang cukup jelas untuk dimiliki, karena klien tahu berapa banyak byte yang diunggah/diunduh.

catatan: Saya mengetahui alternatif "polling server untuk kemajuan" (inilah yang saya lakukan sekarang). masalah utama dengan ini (selain kode sisi server yang rumit) adalah bahwa biasanya, saat mengunggah file besar, koneksi pengguna sepenuhnya disiram, karena sebagian besar ISP menawarkan hulu yang buruk. Jadi, membuat permintaan tambahan tidak responsif seperti yang saya harapkan. Saya berharap akan ada cara (mungkin tidak standar) untuk mendapatkan informasi ini, yang dimiliki browser setiap saat.

130
Pete

Untuk byte yang diunggah itu cukup mudah. Cukup pantau acara xhr.upload.onprogress. Peramban mengetahui ukuran file yang harus diunggah dan ukuran data yang diunggah, sehingga dapat memberikan informasi kemajuan.

Untuk byte yang diunduh (saat mendapatkan info dengan xhr.responseText), itu sedikit lebih sulit, karena browser tidak tahu berapa banyak byte yang akan dikirim dalam permintaan server. Satu-satunya hal yang diketahui browser dalam hal ini adalah ukuran byte yang diterimanya.

Ada solusi untuk ini, cukup untuk mengatur header Content-Length pada skrip server, untuk mendapatkan ukuran total byte yang akan diterima oleh browser.

Untuk lebih lanjut, kunjungi https://developer.mozilla.org/en/Using_XMLHttpRequest .

Contoh: Skrip server saya membaca file Zip (dibutuhkan 5 detik):

$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;

Sekarang saya dapat memantau proses pengunduhan skrip server, karena saya tahu panjang totalnya:

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(); 
}
134
albanx

Firefox mendukung acara perkembangan unduhan XHR .

9
Markus Peröbner

Ada diskusi yang bagus tentang Indikator Kemajuan untuk pola AJAX di sini:

http://ajaxpatterns.org/Progress_Indicator

Salah satu pendekatan yang paling menjanjikan tampaknya membuka saluran komunikasi kedua kembali ke server untuk menanyakan berapa banyak transfer telah selesai.

8
Sean McMains
7

Untuk total yang diunggah tampaknya tidak ada cara untuk mengatasinya, tetapi ada sesuatu yang mirip dengan yang Anda inginkan untuk diunduh. Setelah readyState adalah 3, Anda dapat secara berkala meminta responseText untuk mendapatkan semua konten yang diunduh sejauh String (ini tidak berfungsi di IE), hingga semuanya tersedia pada titik mana ia akan beralih ke readyState 4. Total byte yang diunduh pada waktu tertentu akan sama dengan total byte dalam string yang disimpan di responseText.

Untuk pendekatan semua atau tidak sama sekali terhadap pertanyaan unggahan, karena Anda harus memberikan string untuk unggah (dan dimungkinkan untuk menentukan total byte itu) total byte yang dikirim ke readyState 0 dan 1 akan menjadi 0, dan total untuk readyState 2 akan menjadi total byte dalam string yang Anda berikan. Total byte yang dikirim dan diterima di readyState 3 dan 4 akan menjadi jumlah byte dalam string asli ditambah total byte dalam responseText.

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

Result

3
Forums Lover

Jika Anda memiliki akses ke instalasi Apache dan percaya kode pihak ketiga, Anda dapat menggunakan modul progres upload Apache (jika Anda menggunakan Apache; ada juga sebuah modul progres upload nginx ).

Jika tidak, Anda harus menulis skrip yang dapat Anda tekan keluar dari band untuk meminta status file (misalnya memeriksa ukuran file dari file tmp).

Ada beberapa pekerjaan yang sedang berlangsung di firefox 3 Saya percaya untuk menambahkan dukungan kemajuan unggah ke browser, tapi itu tidak akan masuk ke semua browser dan diadopsi secara luas untuk sementara waktu (lebih disayangkan).

2
Aeon