1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 原生input标签实现ajax单文件上传和多文件上传

原生input标签实现ajax单文件上传和多文件上传

时间:2023-02-10 20:45:59

相关推荐

原生input标签实现ajax单文件上传和多文件上传

自己还是一个菜鸟的时候,有次项目经理让我用Java做一个多文件上传的功能。那时候技术学得很渣,最多只能够实现单文件上传。做了一个星期都没有做出来,于是项目经理不留半点情面,当着办公室所有人的面痛批我一顿,让我颜面扫地,当时我对了他一句我大不了辞职嘛。那是我的悲伤记忆,最终和上级领导沟通半天后,确定留下来继续干。经历一些事情后,一个人总是要成长的,我也一样。如果那个简单的功能都做不出来,那我还能够干什么呢?除了提升自己我还能干什么呢?

那次的问题最后是使用SWFUpload插件解决多文件上传问题的,多年之后的今天已经对文件上传信手拈来,不管是使用插件还是原生的input标签。现在来分享一下使用原生input标签上传文件的用法。

AJAX实现单文件上传

<input type="file" name="file" id="uploadFile"οnchange="uploadExcel()" accept=".xls,.xlsx">

input标签可以隐藏也可以显示出来,样式怎么好看自己就怎么改,type,name属性不要忘记。主要是触发input标签的单击事件,然后选择文件。accept属性的作用是可以限制文件的选择类型,不在accept里面的类型的文件不会显示出来。对一般人来说还是能起作用。选择好文件后,触发下一个事件onchange,它是在文件选择好以后执行。重点来了,文件选择好以后需要做的事情,上代码:

let fileType = $('#uploadFile').val();

fileType = fileType.substring(fileType.lastIndexOf('.'));

//文件类型校验

if(fileType !== '.xls' && fileType !== '.xlsx'){

return msgError('操作提示:只能上传xls格式或者xlsx格式的文件!');

}

//获取单个文件

let file = document.getElementById(`uploadFile`).files[0];

//必须创建一个FormData对象,然后将获取到的文件数据添加到对象中,并且要注意inputFile,解析时需要它。

let formData = new FormData();

formData.append('inputFile',file);

$.ajax({

url: '{{projcfg.appurl}}/api/cable/cable_manage_route/uploadExcel',

type: 'post',

data: formData,

cache: false,//上传文件无需缓存

contentType: false,//必须

processData: false,//用于对data参数进行序列化处理 这里必须false

success: function (json) {

if (json.success) {

msgSuccess(`消息提示:${json.msg}`);

$("#dataTable").datagrid("reload");

}else {

msgError(`错误提示:${json.msg}`);

}

$('#importWin').dialog('close');

$('#uploadFile').parent().html('<input type="file" name="file" id="uploadFile" οnchange="uploadExcel()" accept=".xls,.xlsx">');

},

error: function () {

msgError(`错误提示:导入Excel文件出现异常,请稍后重试!`);

},

});

后端node解析核心代码,使用formidable这个包进行解析,java则可以使用对应的包来进行解析。

var form = new formidable.IncomingForm(); //创建上传表单

form.encoding = opts.encoding; //设置字符集

form.uploadDir = opts.uploadDir; //设置上传目录

form.keepExtensions = opts.keepExtensions; //保留文件后缀名

form.maxFieldsSize = opts.maxFieldsSize; //文件大小

form.parse(req, function (error, fields, files) {

if (error) {

reject(error);

} else {

if(files[opts.file_name]){//有附件上传 和uploadFile的名字一样

let filePath = files[opts.file_name].path;

let fileType = filePath.substr(filePath.lastIndexOf(".") + 1);

if (opts.fileTypes.indexOf(fileType) == -1) {

delFile(filePath);

reject(`Excel文件格式错误,请上传格式为${opts.fileTypes}类型的文件!`);

} else {

//处理Excel文件

let userId = 8;//req.session.current_user._id;

resole(filePath);

}

}else{//没有附件上传

reject('没有附件上传!');

}

}

});

测试后完全可行,项目已经上线正常运行。

AJAX实现多文件上传

多文件上传和单文件上传类似,只需要做少量的修改即可。

<input type="file" name="upload_file" id="upload_file" οnchange="upload_picture()" accept=".jpg, .png" multiple/>

第一个需要修改的地方是添加一个multiple属性,它的作用是你可以同时选择多个文件。

function upload_picture() {

//获取文件数据

let formData = new FormData();

let files = document.getElementById("upload_file").files;

formData.enctype = "multipart/form-data";

let fileArray = [].slice.call(files,0);//类数组转换为数组

let fileType = '', file = '', fileSize = '';

//第二个需要修改的地方,循环验证选择的文件和添加文件数据到FormData中

for(let k = 0,klen = fileArray.length; k < klen; k++){

file = fileArray[k];

fileType = fileArray[k].name.substring(fileArray[k].name.lastIndexOf('.') + 1);

if(fileType !== 'jpg' && fileType !== 'png'){

return layer.msg(`操作提示:只能上传jpg格式或者png格式的图片!`);

}

let fileSize = Math.floor(file.size/(1024*1024));

if(fileSize > 2){

return layer.msg(`操作提示:只能上传大小不超过2MB的图片!`);

}

formData.append(`upload_file${k}`,file);//循环遍历把文件对象插到formData对象上

}

if(fileArray.length === 0){

return layer.msg(`操作提示:请先选择需要上传的图片!`);

}

//提交数据

$.ajax({

url: '{{projcfg.base}}/api/kfz/model_manage_route/upload_picture.do',

type: 'post',

data: formData,

cache: false,//上传文件无需缓存

contentType: false,//必须

processData: false,//用于对data参数进行序列化处理 这里必须false

success: function (result) {

if (result.success && result.code === 2000) {

layer.msg(`消息提示:${result.msg}`);

file_arr = result.data;

}else {

layer.msg(`错误提示:${result.msg}`);

}

//重新创建文件上传标签

$('#upload_file_div').html(`<input type="file" name="upload_file" id="upload_file" οnchange="upload_picture()" accept=".jpg, .png" multiple/>`);

},

error: function () {

layer.msg(`错误提示:上传图片出现异常,请稍后重试!`);

},

timeout: 180000,

complete: function () {

//$.messager.progress('close');

}

});

}

后端node解析核心代码:

var form = new formidable.IncomingForm(); //创建上传表单

form.encoding = opts.encoding; //设置字符集

form.uploadDir = opts.uploadDir; //设置上传目录

form.keepExtensions = opts.keepExtensions; //保留文件后缀名

form.maxFieldsSize = opts.maxFieldsSize; //文件大小

form.parse(req, function (error, fields, files) {

if (error) {

reject(error);

}else {

//文件处理

let temp_file,file_path,file_type,flag,path_arr = [],obj = {};

let type_arr = opts.fileTypes.split('|');

Object.keys(files).forEach(function (file_key) {//第三个需要修改的地方,file_key即为上传时添加的不同的名称

temp_file = files[file_key];

obj = {};

if(temp_file){//有附件上传

let file_path = temp_file.path;

let file_type = file_path.substr(file_path.lastIndexOf("."));

flag = flag;

type_arr.forEach(function (item) {

if(item === file_type){

flag = true;

}

});

if(!flag){

delFile(file_path);//文件类型不匹配

reject(`图片格式错误,请上传格式为${opts.fileTypes}类型的图片!`);

}else {

//将图片移动到指定的文件夹

let temp_path = path.join(opts.uploadDir, opts.nowDate, 'verification');

let desc_path = path.join(temp_path, Math.random().toString().substring(2,12) + file_type);

//处理路径

obj.file_path = desc_path.replace(/\\/g,'/');

obj.file_name = temp_file.name;

path_arr.push(obj);

mkdirsSync(temp_path,'0779');//创建文件夹

fs.renameSync(file_path,desc_path);

}

}

});

if(path_arr.length === Object.keys(files).length){

//返回文件路径

resole(path_arr);

}else{

reject('文件上传出现错误,请稍后重试!');

}

}

});

项目中已经正式采用这种方法,完全可行,目前还没有发现其他问题。

注意事项

如果有文件选择错误的话或者是想重新选择,在不刷新页面的情况下,则需要替换掉原来的input标签。这个好比一次性注射器用一次就扔掉,当然吸毒的除外,每一个用于文件上传的input标签只能使用一次。采用这种处理方式可以将文件上传和数据提交完全分离开来,处理起来非常方便。如果使用form表单提交的方式,则文件上传和其他表单数据一起提交,不排除会容易出现一些未知错误。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。