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

本文采用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/文件名"/>,把文件名传递到前端即可


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值