2012-06-08 30 views
13

Tôi đang cố gắng triển khai thanh tiến trình tải lên theo cách HTML5, bằng cách sử dụng hỗ trợ cấp 2 XMLHttpRequest cho các sự kiện tiến trình.Tại sao XMLHttpRequest ProgressEvent.lengthComputable có thể sai?

Trong mỗi ví dụ bạn thấy, phương pháp này là thêm một người biết lắng nghe sự kiện cho sự kiện tiến bộ như vậy: ví dụ

req.addEventListener("progress", function(event) { 
    if (event.lengthComputable) { 
     var percentComplete = Math.round(event.loaded * 100/event.total); 
     console.log(percentComplete); 
    } 
}, false); 

như vậy dường như luôn cho rằng event.lengthComputable sẽ thành sự thật. Sau khi tất cả, trình duyệt biết chiều dài của yêu cầu nó gửi, chắc chắn?

Không có vấn đề gì tôi làm, event.lengthComputable là sai. Tôi đã thử nghiệm điều này trong Safari 5.1.7 và Firefox 12, cả trên OSX.

Trang web của tôi được xây dựng bằng cách sử dụng Django và tôi gặp vấn đề tương tự trên thiết lập sản xuất và phát triển của mình.

Mã đầy đủ Tôi đang sử dụng để tạo ra các hình thức upload được hiển thị bên dưới (sử dụng jQuery):

form.submit(function() { 
    // Compile the data. 
    var data = form.serializeArray(); 
    data.splice(0, 0, { 
     name: "file", 
     value: form.find("#id_file").get(0).files[0] 
    }); 
    // Create the form data. 
    var fd = new FormData(); 
    $.each(data, function(_, item) { 
     fd.append(item.name, item.value); 
    }); 
    // Submit the data. 
    var req = new XMLHttpRequest(); 
    req.addEventListener("progress", function(event) { 
     if (event.lengthComputable) { 
      var percentComplete = Math.round(event.loaded * 100/event.total); 
      console.log(percentComplete); 
     } 
    }, false); 
    req.addEventListener("load", function(event) { 
     if (req.status == 200) { 
      var data = $.parseJSON(event.target.responseText); 
      if (data.success) { 
       console.log("It worked!") 
      } else { 
       console.log("It failed!") 
      } 
     } else { 
      console.log("It went really wrong!") 
     } 
    }, false); 
    req.addEventListener("error", function() { 
     console.log("It went really really wrong!") 
    }, false); 
    req.open("POST", "/my-bar/media/add/"); 
    req.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 
    req.send(fd); 
    // Don't really submit! 
    return false; 
}); 

Tôi đã xé tóc của tôi ra hàng giờ đồng hồ về vấn đề này. Bất kỳ trợ giúp nào được đánh giá cao!

+0

tôi gặp phải vấn đề này, quá. Dường như FormData() làm cho lengthComputable == false. – est

Trả lời

30

Hey tôi thấy the answer từ @ComFreek:

Tôi đã sai lầm tương tự.

Dòng tôi đã viết là:

xhr.onprogress = uploadProgress; 

Các điều đúng nên

xhr.upload.onprogress = uploadProgress; 
+2

Cảm ơn lời khuyên này! Thật khó để tìm thấy ... – Gregoire

+1

Một nghìn lần cảm ơn bạn! Làm việc như người ở! – Alex

+0

ya anh hùng của tôi, nhưng tôi nên đọc đúng hơn mà tôi đã biết trước đây: D – Can

1

Tôi cũng gặp sự cố khi gửi nhiều tệp lớn bằng AJAX (xmlhttprequest).

Tìm thấy giải pháp và đây là toàn bộ tập lệnh tôi sử dụng. Tất cả bạn cần là đặt dòng tiếp theo trong trang HTML của bạn:

<input type="file" multiple name="file" id="upload_file" onchange="handleFiles(this)"> 

và sử dụng kịch bản tiếp theo:

<script type="text/javacript"> 
    var filesArray; 
    function sendFile(file) 
    { 
     var uri = "<URL TO PHP FILE>"; 
     var xhr = new XMLHttpRequest(); 
     var fd = new FormData(); 

     var self = this; 

     xhr.upload.onprogress = updateProgress; 
     xhr.addEventListener("load", transferComplete, false); 
     xhr.addEventListener("error", transferFailed, false); 
     xhr.addEventListener("abort", transferCanceled, false); 
     xhr.open("POST", uri, true); 
     xhr.onreadystatechange = function() { 
      if (xhr.readyState == 4 && xhr.status == 200) { 
       alert(xhr.responseText); // handle response. 
      } 
     }; 
     fd.append('myFile', file); 
     // Initiate a multipart/form-data upload 
     xhr.send(fd); 
    } 
    function updateProgress (oEvent) 
    { 
     if (oEvent.lengthComputable) 
     { 
      var percentComplete = oEvent.loaded/oEvent.total; 
      console.log(Math.round(percentComplete*100) + "%"); 
     } else { 
      // Unable to compute progress information since the total size is unknown 
      console.log("Total size is unknown..."); 
     } 
    } 

    function transferComplete(evt) 
    { 
     alert("The transfer is complete."); 
    } 

    function transferFailed(evt) 
    { 
     alert("An error occurred while transferring the file."); 
    } 

    function transferCanceled(evt) 
    { 
     alert("The transfer has been canceled by the user."); 
    } 
    function handleFiles(element) 
    { 
     filesArray = element.files; 
     if (filesArray.length > 0) 
     { 
      for (var i=0; i<filesArray.length; i++) 
      { 
       sendFile(filesArray[i]); 
      } 
      filesArray = ''; 
     } 
    } 
    </script> 

Kết quả của bạn sẽ nằm trong diện điều khiển

Các vấn đề liên quan