首先是建个input
注意项: accept里禁止写* 通配符 多选的配置:multiple
方法1 小文件上传
利用FileReader获取文件 体验即时显示文件信息
infoTable.find('.uploadInput').change(function () {
var fileObj = $(this);
var inputName = $(this).attr('name');
var fileNode = fileObj[0].files[0];
var reader = new FileReader();
reader.onload = function (e) {
var base64Data = e.target.result;
fileData[inputName] = dataURLtoBlob(base64Data);
};
if(fileNode) reader.readAsDataURL(fileNode);
});
base64的字符串可以转为blob文件
function dataURLtoBlob(dataurl) {
var arr = dataurl.split(',');
var mimeArray = arr[0].match(/:(.*?);/);
if(!mimeArray || !mimeArray[1]) {
console.log(mimeArray);
console.log('no find 1');
return;
}
var 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 Blob([u8arr], {type: mime});
}
缺点:
FileReader不支持大文件,大概加载不了500M左右以上的超大文件; 文件提交的内容不是原生的文件流对象,而是base64的字符串或是转换成blob二进制文件,所以从它们俩个内容都是获取不到文件名的,需要在获取文件信息时捕获文件名,跟blob对象一起打包提交给后台。
优点:
可以在选择文件时 实时预览文件的信息(缩略图、文件名、文件大小,图片宽高)。 利用这个方法,做一个批量上传的插件。只要将每次批量选择的结果:$(this)[0].files 解析成base64的字符串,显示在列表中,缓存为临时对象,即可控制上传。
方法2 大文件上传
利用原生js方法 new FormData(form.node); 打包生成原生的文件流对象 举例:
$('#demoForm').on('submit', function(e) {
e.preventDefault();
var form_ = $(this);
var formData = new FormData(form[0]);
$.post({
url: '',
data: formData,
})
})
优点:
原生方法,后台可以用files对象获取文件的所有信息
缺点:
前端不能实现:预览文件效果,提前获取文件信息。
多个文件是一次上传,不能改为单个文件上传。
不能用同一个文件input动态创建多个文件,只能在页面上提前生成多个file.input再选择上传。
因为文件流内容无法存入页面dom。
方法1 选择本地文件,获取base64内容显示在本地,即将上传的demo
var fileData = [];
var bindFIleInputEven = function (jqInput) {
var addFileList = function(fileNode) {
var reader = new FileReader();
var fileName = fileNode.name;
var isImg = /(jpg|jpeg|gif|png|bmp|webp)$/i.test(fileName);
var bs = reader.readAsBinaryString, spark = bs ? new SparkMD5() : new SparkMD5.ArrayBuffer();
reader.onload = function (e) {
var fileBase64 = this.result;
spark.append(fileBase64);
//创建文件成功后 删除input防止同一个文件不支持二次选择
var newInput = $(jqInput.prop('outerHTML'));
jqInput.after(newInput);
bindFIleInputEven(newInput);
let imgHash = spark.end();
if(fileData[imgHash]) {
alert('file exist');
return;
}
fileData[imgHash] = fileBase64;
var newFileDom = $('');
infoTable.find('.appendFileBox').append(newFileDom);
newFileDom.find('.removeFileBtn').click(function () {
newFileDom.remove();
delete fileData[imgHash];
})
};
reader.readAsDataURL(fileNode);
};
jqInput.change(function () {
var fileObj = $(this);
var fileNodesList = fileObj[0].files;
$.each(fileNodesList, function (n, fileNode) {
addFileList(fileNode);
});
});
};
var fileUrls = [];
bindFIleInputEven(infoTable.find('.addFileBtn input'));
var uploadFiles = function(base64List, index) {
var firstKey = Object.keys(fileData)[0];
var firstStr = base64List[firstKey];
var album = $(infoTable.find('.appendFileBox').find('.thumbnail').eq(index));
album.addClass('showLoading');
var fileName = album.attr('data-name');
front.postAndDone({
url: '/index/support/upload_warranty_file',
postData: {
fileName: fileName,
base64: firstStr,
},
successKey: 'code',
successVal: 1,
successFunc: function (res) {
lrBox.msgTisf(res.msg);
delete base64List[firstKey];
$(infoTable.find('.appendFileBox').find('.thumbnail').eq(index)).removeClass('showLoading').addClass('showSuccess');
if(Object.keys(fileData).length) {
index++;
uploadFiles(base64List, index);
} else {
lrBox.noLoading();
warrantyBox.trigger('submit');
}
var newUrl = res.data.url;
fileUrls.push({
'fileName': fileName,
'url': newUrl,
})
},
errorFunc: function (res) {
$(infoTable.find('.appendFileBox').find('.thumbnail').eq(index)).removeClass('loading').addClass('showError');
lrBox.noLoading();
lrBox.msgTisf(res.msg);
}
})
};
文件MD5算法js:
/upload/post_files/484/spark-md5.js