利用 <input mutiple="mutiple" type="file"/>
input.files 获取要上传的图片
上传文件用到 formData(延申知识点)
FormData
接口提供了一种表示表单数据的键值对 key/value
的构造方式,并且可以轻松的将数据通过XMLHttpRequest.send()
方法发送出去,本接口和此方法都相当简单直接。如果送出时的编码类型被设为 "multipart/form-data"
,它会使用和表单一样的格式。
FormData.append()
向 FormData
中添加新的属性值,FormData
对应的属性值存在也不会覆盖原值,而是新增一个值,如果属性不存在则新增一项属性值。FormData.delete()
从 FormData 对象里面删除一个键值对。
FormData.entries()
返回一个包含所有键值对的iterator
对象。
FormData.get()
返回在 FormData
对象中与给定键关联的第一个值。
FormData.getAll()
返回一个包含 FormData
对象中与给定键关联的所有值的数组。
FormData.has()
返回一个布尔值表明 FormData
对象是否包含某些键。
FormData.keys()
返回一个包含所有键的iterator
对象。
FormData.set()
给 FormData
设置属性值,如果FormData
对应的属性值存在则覆盖原值,否则新增一项属性值。
FormData.values()
返回一个包含所有值的iterator
对象。
参数为 FormData 中设置的
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> <head> <meta charset="UTF-8" /> <title>Insert title here</title> </head> <body> <h1 th:inlines="text">文件上传</h1> <h2>分片上传</h2> <p>选择文件: <input type="file" id="file" name="file"/></p> <p><input type="submit" value="提交" onclick="commit()"/></p> </body> </html> <script> // 每个文件切片大小定为1M(1024*1024字节)(需要跟服务器协商好). var BYTES_PER_SLICE = 1024 * 1024; // 已发送的数量 var hasSendNum = 0; // 总切片数 var totalSlices; // 提交方法 function commit() { // 拿出选中的第一个文件 var file = document.getElementById("file").files[0]; // 文件的总字节数 var totalSize = file.size; // 当前片数 var index = 0; // 分片的开始、结束(不含) var start,end; // 文件名 var fileName = file.name; // 初始化已发送数量为0 hasSendNum = 0; // 计算文件切片总数(向上取整) totalSlices = Math.ceil(file.size / BYTES_PER_SLICE); // 不断循环将切片上传 while(index < totalSlices) { start = index*BYTES_PER_SLICE; end = start + BYTES_PER_SLICE; var slice =file.slice(start,end);//切割文件 uploadFile(slice, index++,fileName); } } //上传文件 function uploadFile(slice, index,fileName) { var retry = 1; var formDate = new FormData(); formDate.append("slice", slice); formDate.append("fileName",fileName); formDate.append("index",index); var xhr = new XMLHttpRequest(); xhr.open('POST', 'sliceUpload', true);//false指同步上传,因为我的服务器内存较小,选择同步,如果追求速度,可以选择 //ture,异步上传 xhr.onreadystatechange = ()=>uploadCallBack(xhr,slice,index,fileName); xhr.send(formDate); } /** * @desc 上传回调 * @param xhr */ function uploadCallBack(xhr,slice,index,fileName) { if(xhr.readyState==4) { if(xhr.status==200) { if(xhr.responseText==1) { hasSendNum++; console.log("第"+index+"片,完成度"+parseInt(hasSendNum/totalSlices*100)+"%"); if(hasSendNum==totalSlices) { console.log("上传完毕"); } } } else { console.log("上传失败,重试##################################"); // 重试 uploadFile(slice, index,fileName); } } } </script>