How to upload a file with ajax in small chunks and check for fails, re-upload the parts that failed.

前端 未结 2 1928
旧时难觅i
旧时难觅i 2021-02-03 15:31

I have a file uploaded by a user, and I\'d like to achieve the following.

  1. Divide the file into smaller chunks about a megabyte.
  2. Upload each chunk, and wai
相关标签:
2条回答
  • 2021-02-03 15:37

    I've modified afzalex's answer to use readAsArrayBuffer(), and upload the chunk as a file.

        var loaded = 0;
        var reader = new FileReader();
        var blob = file.slice(loaded, max_chunk_size);
        reader.readAsArrayBuffer(blob);
        reader.onload = function(e) {
          var fd = new FormData();
          fd.append('filedata', new File([reader.result], 'filechunk'));
          fd.append('loaded', loaded);
          $.ajax(url, {
            type: "POST",
            contentType: false,
            data: fd,
            processData: false
          }).done(function(r) {
            loaded += max_chunk_size;
            if (loaded < file.size) {
              blob = file.slice(loaded, loaded + max_chunk_size);
              reader.readAsArrayBuffer(blob);
            }
          });
        };
    
    0 讨论(0)
  • 2021-02-03 15:52

    You are not doing anything for failure of any chunk upload.

    $.chunky = function(file, name){        
        var loaded = 0;
        var step = 1048576//1024*1024; size of one chunk
        var total = file.size;  // total size of file
        var start = 0;          // starting position
        var reader = new FileReader();
        var blob = file.slice(start,step); //a single chunk in starting of step size
        reader.readAsBinaryString(blob);   // reading that chunk. when it read it, onload will be invoked
    
        reader.onload = function(e){            
            var d = {file:reader.result}
            $.ajax({
                url:"../record/c/index.php",
                type:"POST", 
                data:d                     // d is the chunk got by readAsBinaryString(...)
            }).done(function(r){           // if 'd' is uploaded successfully then ->
                    $('.record_reply_g').html(r);   //updating status in html view
    
                    loaded += step;                 //increasing loaded which is being used as start position for next chunk
                    $('.upload_rpogress').html((loaded/total) * 100);
    
                    if(loaded <= total){            // if file is not completely uploaded
                        blob = file.slice(loaded,loaded+step);  // getting next chunk
                        reader.readAsBinaryString(blob);        //reading it through file reader which will call onload again. So it will happen recursively until file is completely uploaded.
                    } else {                       // if file is uploaded completely
                        loaded = total;            // just changed loaded which could be used to show status.
                    }
                })              
            };
    }
    

    EDIT

    To upload failed chunk again you can do following :

    var totalFailures = 0;
    reader.onload = function(e) {
        ....
    }).done(function(r){
        totalFailures = 0;
        ....
    }).fail(function(r){   // if upload failed
       if((totalFailure++) < 3) { // atleast try 3 times to upload file even on failure
         reader.readAsBinaryString(blob);
       } else {                   // if file upload is failed 4th time
          // show message to user that file uploading process is failed
       }
    });
    
    0 讨论(0)
提交回复
热议问题