首页 > 技术文章 > AJAX大文件切割上传以及带进度条。

pssp 2016-09-01 22:21 原文

分块传输的原理就是利用HTML5新增的文件slice截取函数。

 

代码如下:

html:

<input id="f" type="file" name="part" onchange="writeFile()">

JS:

核心部分已经加粗显示了,其他部分不用看,因为实现的方式有很多种,不一定要按照我的方式去写,但是核心是不会变的。

var writeFile = function(){
  var temp = null;
  var formData = null;
  var xhr = null;

  var file = document.getElementById('f');
  var f = file.files[0];
  var totalSize = f.size;

  // 每次截取的大小
  var num = 1024*1024;

  var start = 0;
  var end = start + num;

  // 发送到的地址
  var url = 'http://127.0.0.1/index.php';

  // 进度条
  var loaded = function(bili){
    console.log(bili);
  };

  writeFile = function(){
    // 如果已经截取完了跳出这个函数。
    if(start>=totalSize)return;

    // 截取文件
    temp = f.slice(start,end);


    formData = new FormData();
    formData.append(file.name,temp);

    xhr = new XMLHttpRequest();
    xhr.open('POST',url);

    xhr.onreadystatechange = function(){
      if(this.readyState===4 && this.status===200){
        // 改变下一次截取的位置
        start = end;
        end = start + num;
        // 因为截取可能超过totalSize,判断最后一次截取是否大于totalSize如果大于就直接让end等于totalSize
        if(end>totalSize){
          end = totalSize;
        }
        // 可以用这个做进度条
        loaded((start/totalSize)*100);
        // 递归,如果文件没有截取完,继续截取
        writeFile();
      }
    };
    xhr.send(formData);
  };

  // 调用一下
  writeFile();
};

当然除了这些还是不够的,后端也是需要处理一下的,因为现在发送过去的文件是一块一块的,所有需要合并一下,不过已经和前端没有关系了,但我还是给出代码吧。

<?php

// 判断是否有这个文件
if(!file_exists('./a/up.wmv')){

  //创建一个文件
  move_uploaded_file($_FILES['part']['tmp_name'],'./a/up.wmv');
}else{

  //将前面的那个文件和当前这个文件合并,FILE_APPEND把当前这个内容追加上去。
  file_put_contents('./a/up.wmv',file_get_contents($_FILES['part']['tmp_name']),FILE_APPEND);
  echo 'ok';
}

?>

 

推荐阅读