问题背景
项目在移动端因为图片过大,需要进行切片上传处理。(仅涉及前端逻辑)
判断是否断网
/* 主要解决缓存了当前页面之后 用户断网再上传图片出现的逻辑错误*/
if ( navigator.onLine ) {
//正常工作
} else {
//执行离线状态时的任务
}
单文件上传模拟进度条
animatePress(obj) {
let randNum = this.getRandomNum(80, 95);
var setIntVal = setInterval(() => {
if (obj.press < randNum) {
if (obj.press < 20) {
obj.press++;
} else {
obj.press += 3;
}
}
if (obj.press == 100) {
clearInterval(setIntVal);
}
}, 100);
},
单文件 获得一个 x- y 之间的随机数
getRandomNum(min, max) {
let range = max - min;
let rand = Math.random();
return min + Math.round(rand * range);
},
图片上传转base64
https://blog.csdn.net/lhjllff12345/article/details/72842384
$("#img_upload_file").change(function() {
var file = this.files[0];
var reader = new FileReader();
reader.readAsDataURL(file);//调用自带方法进行转换
reader.onload = function(e) {
$("#img_upload_show").attr("src", this.result);//将转换后的编码存入src完成预览
$("#img_upload_base").val(this.result);//将转换后的编码保存到input供后台使用
};
});
怎么获取文件数据
// capture 相机属性 multiple 多选文件
<input type="file" accept="image/*" capture="camera" multiple="multiple" id="take-photo" @change="takePhoto">
<input type="file" accept="image/*" multiple="multiple" id="take-photo" @change="takePhoto">
<script>
takePhoto: function(e) {
console.log(e.target.files.length)
},
</script>
js判断文件类型、文件大小
const name = files.name;
const nameType = name.substring(name.lastIndexOf('.')+1).toUpperCase();;
console.log(nameType);
if( nameType != 'JPG' && nameType != 'JPEG' && nameType != 'PNG' ){
alert('图片类型出错')
}
if (file.size > 1024 * 10 * 1024) {
alert("图片大小不允许超过10M")
}
怎么进行本地预览展示
<img :src="getObjectURL(value.file)" :alt="value.fileid" class="img-box-src">
getObjectURL(file) {
var url = null;
if (window.createObjectURL != undefined) {
// basic
url = window.createObjectURL(file);
} else if (window.URL != undefined) {
// mozilla(firefox)
url = window.URL.createObjectURL(file);
} else if (window.webkitURL != undefined) {
// webkit or chrome
url = window.webkitURL.createObjectURL(file);
}
return url;
},
将base64转换为文件
https://blog.csdn.net/yin13037173186/article/details/83302628
//将base64转换为blog再转为文件 兼容ios 11.4以下
dataURLtoBlob(base64,fileName) {
var arr = base64.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
let theBlob = new Blob([u8arr], {
type: mime });
theBlob.lastModifiedDate = new Date();
theBlob.name = fileName;
return theBlob;
},
//将base64转换为文件 不兼容ios11.4以下
dataURLtoFile(dataurl, filename) {
var arr = dataurl.split(","),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, {
type: mime });
},
怎么去切割图片
// 分片上传文件
// file,nowcount,start,end
// 文件,目前上传次数,切片开始值,切片结束值
axiosSliceFile(obj, nowcount, start, end) {
var that = this;
var sliceSize = 1024 * 1024;
// 文件段上传
var sizeImg = obj.file.size;
// 第一段开始值
var startImg = start;
// 第一段结束值
var endImg = end;
// 目前上传次数
var countImg = nowcount;
// 总上传次数
var sliceCount = Math.ceil(obj.file.size / sliceSize) - 1;
// 切分片的file文件
var dataImg = obj.file.slice(startImg, endImg);
// 创建一个reader
let dataImgReader = new FileReader();
// 将图片2将转成 base64 格式
dataImgReader.readAsDataURL(dataImg);
dataImgReader.onloadend = function() {
// 分片转为file文件
var fileImg = that.dataURLtoBlob(this.result, obj.file.type);
// // md5 分片的file文件
// var sliceMd5File = "";
// var reader = new FileReader();
// reader.readAsText(dataImg);
// reader.onload = function(e) {
// let bolb = e.target.result;
// sliceMd5File = md5(bolb);
// };
// 进度条加载
that.animateSlicePress(obj, sliceCount, countImg);
// md5 所有的文件
let readerFile = new FileReader();
readerFile.readAsText(obj.file);
var md5File = "";
readerFile.onload = function(e) {
let bolb = e.target.result;
md5File = md5(bolb);
// console.log(md5File, "file的md5文件");
var newParaMeters = {
sliced: true,
filename: obj.file.name,
file: fileImg,
md5_value: md5File,
total_size: obj.file.size,
slice_count: sliceCount + 1,
slice_index: countImg,
slice_size: endImg - startImg
};
console.log("正在上传" + countImg + "块切片", newParaMeters);
let fd = new FormData();
fd.append("sliced", newParaMeters.sliced);
fd.append("filename", newParaMeters.filename);
fd.append("file", newParaMeters.file);
fd.append("md5_value", newParaMeters.md5_value);
fd.append("total_size", newParaMeters.total_size);
fd.append("slice_count", newParaMeters.slice_count);
fd.append("slice_index", newParaMeters.slice_index);
fd.append("slice_size", newParaMeters.slice_size);
let config = {
headers: {
"Content-Type": "multipart/form-data"
}
};
// that.axios
// .post(dataUrl + "enroll/pic_upload", fd, config)
requestUpFile(fd, config)
.then(res => {
// console.log(res, "多文件上传请求成功");
// 该文件已经上传过了
if (res.data.code == 2003) {
that.$vux.toast.show({
text: "系统已过滤重复作品",
time: 1000,
type: "cancel"
});
let upObjT = {
picture_id: res.data.data.picture_id,
path: res.data.data.picture_url,
file: obj.file
};
that.animateSuccess(obj, upObjT, true);
}
// 整个文件上传完成
if (res.data.code == 2001) {
let upObjT = {
picture_id: res.data.data.picture_id,
path: res.data.data.picture_url,
file: obj.file
};
that.animateSuccess(obj, upObjT, false);
}
// 切片上传完成
if (res.data.code == 2002) {
countImg++;
if (countImg <= sliceCount) {
startImg = endImg;
if (sliceCount - countImg < 1) {
endImg = sizeImg;
} else {
endImg += sliceSize;
}
that.axiosSliceFile(obj, countImg, startImg, endImg);
}
that.animateSlicePress(obj, sliceCount, countImg);
}
// 上传进度错误
if (res.data.code == 2004) {
countImg = parseInt(res.data.data.finished_index) + 1;
startImg = countImg * sliceSize;
if (sliceCount - countImg < 1) {
endImg = sizeImg;
} else {
endImg += sliceSize;
}
// console.log(obj, countImg, startImg, endImg);
that.axiosSliceFile(obj, countImg, startImg, endImg);
that.animateSlicePress(obj, sliceCount, countImg);
}
// 上传出错
if (res.data.code == 4001) {
console.log(res.data,'上传出错4001');
obj.reUpload = true;
}
})
.catch(res => {
// 请求出错
obj.reUpload = true;
});
};
}
},
推荐阅读:
https://www.cnblogs.com/conglvse/p/9524452.html
https://blog.csdn.net/haohao123nana/article/details/51279098
https://blog.csdn.net/qq_42245281/article/details/81263303
https://www.cnblogs.com/XuYuFan/p/10209277.html
https://www.cnblogs.com/hello-word1/archive/2016/03/09/5259064.html
https://segmentfault.com/a/1190000009448892?utm_source=tag-newest