您的位置:首页 > Web前端 > JQuery

一键jquery异步上传文件(图片)的实现(文件上传进度读取未做)

2017-03-15 20:45 771 查看
本文采用boostrap、、jquery、jade(html的一种模板)、nodejs实现

最终实现的效果:一个按钮在选择完文件后,自动上传到后台;

-改变input样式

在form表单中,用<a>包裹<input type="file">,让input隐藏,jade代码如下

form#index_new.form-horizontal(method="post",role="form",action="/admin/index/save",enctype="multipart/form-data")
input(type="hidden",name="index[_id]",value="#{index._id}")
.col-sm-2
a.btn.btn-primary.upload_index_img_box 添加图片
input(type="hidden",name="posterType",value="index")
input#upload_index_img(type="file",name="upload_poster")


其中第一个input(type="hidden")的作用是用来提交表单的数据index的_id到后台服务器,以使得后台接收到index._id的时候为'undefined'(个人处理习惯)

第二个input(type="hidden")的作用是用来提交图片类型到后台,也就是posterType='index'这个值,作为标识符,以方便文件的分类管理

利用”事件捕获“和”事件冒泡“,给外层a绑定点击事件来触发内层的input(type="file")以选择文件,源代码如下

var btnChooseFile = $('.upload_index_img_box');
var btnChooseHide = $('#upload_index_img');
btnChooseFile.click(function(event){
event.stopPropagation();
console.log(event.target);
console.log(this);
if (event.target==this) {
btnChooseHide.click();

}
});


其中.stopPropagation()用来阻止<a>的默认动作(似乎没有派上用场),由event.target==this来确保点击的对象是外层的<a>

为内层隐藏的input(type="file")设置.change()监听,上传结束时,触发ajax,向服务器端发送数据:

btnChooseHide.change(function(event){
if (btnChooseHide.val()!=='undefined') {
//html5的生成的表单数据对象
var form = new FormData($('#index_new')[0]);
$.ajax({
url: '/admin/index/save',
type: 'post',
//发送到服务器端的数据的格式,取消默认编码格式
contentType:false,
dataType:'json',
data: form,
//因为是图片,不要对其作序列化处理
processData:false,
success: function (data) {
if (data){
//对服务器返还的数据进行拼接处理
var id = data.index._id;
var img = data.index.img;
var date = data.index.meta.updateAt.split('T')[0];
var html = $('<tr class="item-id-'+id+'"></tr>')
var tdName = $('<td><a class="thumbnail"><img src="/upload/index/'+img+'" alt="点击查看大图"/></a></td>');
var tdDate = $('<td>'+date+'</td>');
var del = $('<td><button class="btn btn-danger del" type="button" data-id="'+id+'" data-type="index">删除</button></td>')
html.appendTo(tbody);
tdName.appendTo(html);
tdDate.appendTo(html);
del.appendTo(html);
}
},
err:function(jqHXR){
console.log(jqXHR.status);
}
});
return false;
}
});


这其中contentType不能设置为multipart/form-data,否则会报错。关键的三点是contentType、dataProcess、new FormData(),否则文件无法传到后台。

服务器端实现:

根据传过来的数据,进行一系列处理后,以初始路径地方式读取传过来的文件,再生成新的指定路径和新的文件名称,将文件写入到该路径下。完成文件的存储后,将数据传给前端,前端以jquery的方式对数据进行拼接插入,从而实现异步更新。

此外,数据还要对模板进行渲染,否则刷新页面后无法显示。

处理图片上传的中间件如下:

var fs = require('fs');
var path = require('path');
exports.save_poster = function(req,res,next){
console.log('req.files');
console.log(req.files);
var posterData = req.files.upload_poster;
var posterType = req.body.posterType;
var filePath = posterData.path;
var originalFilename = posterData.originalFilename;
if (originalFilename) {
fs.readFile(filePath,function(err,data){
//生成日期
var timestamp = Date.now();
//获取图片格式
var type = posterData.type.split('/')[1];
//由“日期.图片格式”生成文件名
var posterName = timestamp+'.'+type;
//__dirname获取当前文件夹(只是文件夹,不包括文件本身)的绝对路径
//合并下面的路径生成图片文件的存储路径
var newPath = path.join(__dirname,'../../','/public/upload/'+posterType+'/'+posterName);
fs.writeFile(newPath,data,function(err){
req.poster = posterName;
next();
});
});
}
else{
next();
}
};
前端图片的显示,以路径的方式显示即可,比如<img  src="/upload/index/文件名"/>,把文件名传递到前端即可
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  nodejs 表单 jquery 图片