<script>
initUpload();
//初始化上传
function initUpload() {
var chunk = 100 * 1024; //每片大小
var input = document.getElementById("file"); //input file,获取上传文件
input.onchange = function (e) {//文件筐选中文件触发事件
var file = this.files[0];//得到文件对象
var query = {};//ajax的数据
var chunks = [];//存放切片文件
if (!!file) {//undifined和null时,用一个感叹号返回的都是true,用两个感叹号返回的就是false,如果明确设置了变量的值(非null/undifined/0/""等值),结果就会根据变量的实际值来返回,如果没有设置,结果就会返回false。
var start = 0;//切片开始位置
//文件分片
for (var i = 0; i < Math.ceil(file.size / chunk); i++) {//循环,结束条件是文件大小/每片大小向上取整
var end = start + chunk;//结束位置等于起始位置加每片大小
chunks[i] = file.slice(start , end);//文件使用slice方法确定起止位置切片数据放入数组
start = end;//开始位置重定义为上次结束位置,进入下次循环
}
// 采用post方法上传文件
// url query上拼接以下参数,用于记录上传偏移
// post body中存放本次要上传的二进制数据
query = {//数据
fileSize: file.size,//文件大小
dataSize: chunk,//每片大小
nextOffset: 0//下次偏移
}
upload(chunks, query, successPerUpload);//执行方法,参数1是文件切片数组,参数二是query数组,参数三是每片上传完后重新调用upload方法,所有切片上传完后,结束调用类似递归
}
}
}
// 执行上传
function upload(chunks, query, cb) {//上传方法:参数1是文件切片数组,参数二是query数组,参数三是每片上传完后重新调用upload方法,所有切片上传完后,结束调用类似递归
var queryStr = Object.getOwnPropertyNames(query).map(key => {
return key + "=" + query[key];
}).join("&");//组合成拼接字符串
var xhr = new XMLHttpRequest();//ajax请求
xhr.open("POST", "http://xxxx/opload?" + queryStr);//请求地址,加拼接参数
xhr.overrideMimeType("application/octet-stream");//二进制文件格式
//获取post body中二进制数据
var index = Math.floor(query.nextOffset / query.dataSize);//位移/大小,向下取整
getFileBinary(chunks[index], function (binary) {//调用方法获取二进制数据,参数1是当前片数,参数二回调函数
//在调用函数后,得到函数获取的result 属性中将包含一个 ArrayBuffer 对象以表示所读取文件的数据。在发送二进制数据
if (xhr.sendAsBinary) {//如果是二进制,已经快要废除的方法
xhr.sendAsBinary(binary);//就按二进制发送
} else {
xhr.send(binary);//直接发送
}
});
xhr.onreadystatechange = function (e) {//ajax回调
if (xhr.readyState === 4) {//ajax呼叫成功
if (xhr.status === 200) {//ajax返回成功
var resp = JSON.parse(xhr.responseText);//返回值解析成对象
// 接口返回nextoffset
// resp = {
// isFinish:false,
// offset:100*1024
// }
if (typeof cb === "function") {
cb.call(this, resp, chunks, query)
}
}
}
}
}
// 每片上传成功后执行
function successPerUpload(resp, chunks, query) {//1,ajax返回对象,2数据本身,3是切片参数
if (resp.isFinish === true) {
alert("上传成功");
} else {
//未上传完毕
query.offset = resp.offset;
upload(chunks, query, successPerUpload);
}
}
// 获取文件二进制数据
function getFileBinary(file, cb) {//第一个是文件,第二个是方法
var reader = new FileReader();//FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。
//FileReader 提供的 readAsArrayBuffer() 方法会开始读取制定的 Blob 或 File 对象。
//当读取操作完成的时候,readyState 变成已完成(DONE),并触发 loadend 事件,同时 result 属性中将包含一个 ArrayBuffer 对象以表示所读取文件的数据。
reader.readAsArrayBuffer(file);
reader.onload = function (e) {//读取完文件触发onload事件
if (typeof cb === "function") {//typeof强制转换cb参数得到类型,如果cb是个方法
cb.call(this, this.result);//调用方法的call回调函数,传回reader本身与reader读取完文件的result 属性中将包含一个 ArrayBuffer 对象以表示所读取文件的数据。也就是读取的数据
}
}
}
</script>
<!--总结:
初始化上传执行initUpload()
规定切片大小,得到文件数据,把文件分割成片存入数组,
定义参数
调用upload()上传
Upload方法1个参数是数据,2个参数是参数配置,3个参数是递归方法,切片没完成的时候继续调用
upload里面又有getFileBinary()获取二进制数据,每次发送二进制数据
successPerUpload()方法内在调用upload方法,形成循环链,到切片上传完成结束循环连
-->
initUpload();
//初始化上传
function initUpload() {
var chunk = 100 * 1024; //每片大小
var input = document.getElementById("file"); //input file,获取上传文件
input.onchange = function (e) {//文件筐选中文件触发事件
var file = this.files[0];//得到文件对象
var query = {};//ajax的数据
var chunks = [];//存放切片文件
if (!!file) {//undifined和null时,用一个感叹号返回的都是true,用两个感叹号返回的就是false,如果明确设置了变量的值(非null/undifined/0/""等值),结果就会根据变量的实际值来返回,如果没有设置,结果就会返回false。
var start = 0;//切片开始位置
//文件分片
for (var i = 0; i < Math.ceil(file.size / chunk); i++) {//循环,结束条件是文件大小/每片大小向上取整
var end = start + chunk;//结束位置等于起始位置加每片大小
chunks[i] = file.slice(start , end);//文件使用slice方法确定起止位置切片数据放入数组
start = end;//开始位置重定义为上次结束位置,进入下次循环
}
// 采用post方法上传文件
// url query上拼接以下参数,用于记录上传偏移
// post body中存放本次要上传的二进制数据
query = {//数据
fileSize: file.size,//文件大小
dataSize: chunk,//每片大小
nextOffset: 0//下次偏移
}
upload(chunks, query, successPerUpload);//执行方法,参数1是文件切片数组,参数二是query数组,参数三是每片上传完后重新调用upload方法,所有切片上传完后,结束调用类似递归
}
}
}
// 执行上传
function upload(chunks, query, cb) {//上传方法:参数1是文件切片数组,参数二是query数组,参数三是每片上传完后重新调用upload方法,所有切片上传完后,结束调用类似递归
var queryStr = Object.getOwnPropertyNames(query).map(key => {
return key + "=" + query[key];
}).join("&");//组合成拼接字符串
var xhr = new XMLHttpRequest();//ajax请求
xhr.open("POST", "http://xxxx/opload?" + queryStr);//请求地址,加拼接参数
xhr.overrideMimeType("application/octet-stream");//二进制文件格式
//获取post body中二进制数据
var index = Math.floor(query.nextOffset / query.dataSize);//位移/大小,向下取整
getFileBinary(chunks[index], function (binary) {//调用方法获取二进制数据,参数1是当前片数,参数二回调函数
//在调用函数后,得到函数获取的result 属性中将包含一个 ArrayBuffer 对象以表示所读取文件的数据。在发送二进制数据
if (xhr.sendAsBinary) {//如果是二进制,已经快要废除的方法
xhr.sendAsBinary(binary);//就按二进制发送
} else {
xhr.send(binary);//直接发送
}
});
xhr.onreadystatechange = function (e) {//ajax回调
if (xhr.readyState === 4) {//ajax呼叫成功
if (xhr.status === 200) {//ajax返回成功
var resp = JSON.parse(xhr.responseText);//返回值解析成对象
// 接口返回nextoffset
// resp = {
// isFinish:false,
// offset:100*1024
// }
if (typeof cb === "function") {
cb.call(this, resp, chunks, query)
}
}
}
}
}
// 每片上传成功后执行
function successPerUpload(resp, chunks, query) {//1,ajax返回对象,2数据本身,3是切片参数
if (resp.isFinish === true) {
alert("上传成功");
} else {
//未上传完毕
query.offset = resp.offset;
upload(chunks, query, successPerUpload);
}
}
// 获取文件二进制数据
function getFileBinary(file, cb) {//第一个是文件,第二个是方法
var reader = new FileReader();//FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。
//FileReader 提供的 readAsArrayBuffer() 方法会开始读取制定的 Blob 或 File 对象。
//当读取操作完成的时候,readyState 变成已完成(DONE),并触发 loadend 事件,同时 result 属性中将包含一个 ArrayBuffer 对象以表示所读取文件的数据。
reader.readAsArrayBuffer(file);
reader.onload = function (e) {//读取完文件触发onload事件
if (typeof cb === "function") {//typeof强制转换cb参数得到类型,如果cb是个方法
cb.call(this, this.result);//调用方法的call回调函数,传回reader本身与reader读取完文件的result 属性中将包含一个 ArrayBuffer 对象以表示所读取文件的数据。也就是读取的数据
}
}
}
</script>
<!--总结:
初始化上传执行initUpload()
规定切片大小,得到文件数据,把文件分割成片存入数组,
定义参数
调用upload()上传
Upload方法1个参数是数据,2个参数是参数配置,3个参数是递归方法,切片没完成的时候继续调用
upload里面又有getFileBinary()获取二进制数据,每次发送二进制数据
successPerUpload()方法内在调用upload方法,形成循环链,到切片上传完成结束循环连
-->