手机版

Nodejs express html5实现拖拽上传

时间:2021-10-08 来源:互联网 编辑:宝哥软件园 浏览:

一、前言

文件上传是常用功能,传统的上传方式比较麻烦,需要先点击上传按钮,然后找到文件路径,再上传。它给用户体验带来了很大的问题。Html5开始支持拖放上传所需的api。Nodejs也是最近越来越流行的技术,这也是我第一次接触nodejs。nodejs开发中最常用的开发框架之一是expess,这是一个类似于mvc模式的框架。结合html5和nodejs express,实现了拖拽和上传功能。

二是基础知识的普及。

1.NodeJs的基础知识。

Nodejs只是一个允许js在服务器上运行的开发平台。nodejs发展非常快,国内很多公司已经开始使用淘宝。传统的web应用开发平台依靠多线程来实现对高并发请求的响应。Nodejs采用了单线程、异步IO和事件驱动的设计模式,给nodejs带来了很大的性能提升。这也是nodejs最大的特点。在nodejs中,所有的IO操作都是通过回调来执行的。nodejs在执行IO操作时会将IO请求推送到事件队列,等待程序处理IO,然后调用回调函数返回结果。

例如,在查询数据库时的操作如下:

MySQL . query(' SELECT * FROM my table ',函数(RES){ callback(RES);});在上面的代码中,nodejs执行上面的语句时,不会等待数据库返回结果,而是继续执行下面的语句。数据被数据库获取后,会被发送到事件循环队列,直到线程进入事件循环队列才会执行回调。

这两天看了更多关于nodejs的东西,但是不太了解。要学习更多的知识,你可以在网上搜索。

nodejs http://www .node初学者. org/index-zh-cn . html//www . JB 51 . net/article/48755 . htm简介。

2.快递基础知识。

Nodejs是一个活跃的开源社区,拥有大量的第三方开发库,其中Express是使用最广泛的框架之一。也是nodejs推荐的框架。除了封装常见的http操作,还实现了路由控制、模板解析支持、动态尝试、用户回复等。然而,它不是一个普遍的框架。它的大部分功能是封装http,但它只是一个轻量级框架。许多功能需要与第三方库集成。

Exress为上传功能提供了非常方便的支持。文件上传请求后,express将接收文件并将其存储在临时目录中。然后,在路由方法中,我们只需要将文件从临时目录复制到我们想要存储用户上传的文件夹中。在文件上传部分,服务器的实现基于express的功能。

3.html5拖拽上传api。

Html5提供了许多新功能,其中拖放事件和文件上传是新功能之一。由于篇幅有限,后面主要介绍拖拽上传的代码实现。没有列出html5提供的拖拽上传apil,感兴趣的请参考:http://w3school.com.cn/HTML5/HTML5 _ ref _ eventattributes.asp # mouse _ events//www . JB 51 . net/html 5/85977 . html。

第三,拖拽上传实现。

1.代码实现。

我们先来看看前端js的文件目录:

其中:

Uploader.js主要封装html5支持的上传功能。

UploaderQueue.js主要实现上传文件队列和上传对象的管理,将文件队列中的文件上传到服务器。

UploaderApp.js为主文件上传门户,主要实现通过上传窗口监控拖拽事件,将拖拽文件推送到上传文件队列中,启动文件上传程序。

以下是核心代码的简要说明,所有代码都可以在这里下载:FileUploader。

首先,简单地打包uploader.js来上传html5提供的文件。

函数上传器(网址),数据、文件){这个_文件=文件;这个。_数据=数据;这个_ url=url这个_ xhr=nullthis。onloadstart={ };这个。onload={ };这个。onloadend={ };这个。进行中={ };这个。one rror={ };这个。ontimeout={ };这个。回调={ };//请求完成后回调_ self=this}上传程序。prototype={ init : function(){ if(!isValid()){ throw e;}这个_ xhr=new XMlhttprequest();这个. BindEvents();},send:函数(){如果(这._ xhr==null){ this。init();} var formData=this ._ createFormData();这个. xhr.open('post ',这个. url,true);这个_ xhr。发送(表单数据);},_ bindEvents:函数(){ _ self=this这个_ xhr。上传。load start=function(e){ eval function(_ self)。onload start,e);}这个_ xhr。上传。onload=function(e){ eval function(_ self)。onload,e);};这个_ xhr。上传。onloadend=function(e){ eval function(_ self)。onloadend,e);}这个_ xhr。上传。on progress=function(e){ eval function(_ self)。进度,e)};这个_ xhr。上传。one rror=function(e){ eval function(_ self。一个rror,e);};这个_ xhr。上传。on time out=function(e){ eval function(_ self)。ontimeout,e);}这个_ xhr。onreadystatechange=function(){ if(_ self)._ xhr。ready state==4){ if(self的类型。回调==' function '){ var status=_ self ._ xhr.statusvar数据=_self ._ xhr . responsetext _ self . callback(状态,数据);} } } },_createFormData:函数(){ var formData=new formData();这个_ addDataToFormData(formData);这个_ addFileToFormData(formData);返回formData},_addDataToFormData:函数(formData) { if (this ._data) { for (var项目在此_data) { formData.append(item,this ._ data[item]);} } },addFileToFormData:函数(formData) { if (this ._ files){ for(var I=0;我喜欢这个. files.lengthi ) { var file=this ._文件[一];formData.append('文件[' i ']),这。_文件[I]);} } } };查看Codevar uploaderFactory={ send :函数(网址),数据、文件、回调){新上传者数据、文件);检查器。回调=函数(状态,resData){ if(回调的类型==' function '){回调(状态,resData);} }在PlaAder中。send();返回insUploader } }上传者对象主要是对html5提供的原生美国石油学会(美国石油协会)进行简单的封装上传工厂提供一个简单的接口,使用它可以像jquery的创建交互式、快速动态网页应用的网页开发技术方法一样完成,文件上传调用html5。中提供的文件上传的支持,是在原来XMLHttpRequest基础之上扩展一些属性和方法,提供了表单数据对象,来支持文件上传操作。

文件上传队列(uploaderQueue.js)也是一个比较重要的对象,它包括两个对象一个是排队,文件队列对象,主要负责管理文件队列的增删改查询等操作,另一个对象是上传引擎,文件上传引擎,它的功能主要是负责从文件队列中取出文件对象,调用上传者对象上传文件,然后更新文件队列中的文件状态排队以及上传引擎都是单例对象。

首先来看下文件队列对象:

(函数(上传请求){ var状态={就绪: 0,上传: 1,完成: 2 } var _ self=nullvar实例=null函数Queue() { this ._ datas=[];这个_ curSize=0;//当前长度_ self=this } queue . prototype={ add :函数(数据){ var key=new Date().getTime();这个数据。按压({键:键,数据:数据,状态:状态.ready });这个_curSize=这个._ datas.length返回键;},remove:函数(键){ var index=this ._ GetIndexByKey(key);这个_ datas.splice(索引,1);这个_curSize=这个._ datas.length},get:函数(键){ var index=this ._ GetIndexByKey(key);返回索引!=-1 ?这个。_数据[索引]。数据:为空;},clear:函数(){这个._ datas=[];这个_curSize=这个._ datas.length},size:函数(){返回此_ curSize},setItemStatus:函数(键,状态){ var index=this ._ GetIndexByKey(key);if (index!=-1) {这个。_数据[索引]。状态=状态;} },nextReadyingIndex:函数(){ for(var I=0;我喜欢这个_数据.长度我){如果(这个。_数据[i].状态==状态。就绪){返回我;} } return-1;},getDataByIndex:函数(索引){ if(索引0) {返回null}退回这个_ data[index];},getindexbykey : _ function(key){ for(var I=0;我喜欢这个_数据.长度我){如果(这个。_数据[i].key==key){ return I;} } return-1;} };函数GetInstance(){ if(instance===null){ instance=new Queue();返回实例;} else {返回实例;} } upladerQueue .queue=GetInstance();上传请求。上传状态=状态;})(窗口。上传者队列);上传文件队列使用一个数组管理每个文件对象信息,每个文件对象有密钥、数据、状态三个属性,该对象主要负责文件对象的增加、删除、更新、查找的功能。

上传文件队列中另一个比较重要的对象是上传引擎对象(uploadEngine.js)

(函数(upladerQueue){ var instance=null;var _ self函数uploadEngine() {这个._ url=null这个_ curUploadingKey=-1;//标志这个。uploadstatuschanged={ };这个。uploaditem progress={ };_ self=this} uploadengine。原型={ seturl :函数(URL){ this ._ url=url},run:函数(){如果(这._curUploadingKey===-1这个_url) {这个._ startUpload();} },startupload : _ function(){ _ self=this;定义变量索引=上传请求.排队。next reading index();if (index!=-1) {这个_uploadItem(索引);} else { this ._ curUploadingKey=-1;返回null} },upload item : _ function(index){ var data=upladerQueue .Queue.getDataByIndex(索引)。数据;_ self=这个这个_readyUploadItem(索引);var上传器=上传器工厂。发送(这个._url,null,data.files,函数(状态,数据){ _self ._ completeduploaditem。调用(_ self,状态,数据);});这个。_上传项目进度(上传);},uploadItemProgress:函数(上传){ upload.onprogress=函数(e){ _ self。uploaditempress(_ self)._curUploadingKey,e);} },readyUploadItem:函数(索引){这个._curUploadingKey=upladerQueue .Queue.getDataByIndex(索引)。钥匙;if(这种类型。uploadstatuschanged==' function '){ this。uploadstatuschanged(这._curUploadingKey,upladerQueue .上传状态。上传);}上传请求.Queue.setItemStatus(这_curUploadingKey,upladerQueue .上传状态。上传);},_ completedUploadItem:函数(状态,数据){ if(这种类型。uploadstatuschanged==' function '){ this。uploadstatuschanged(这._curUploadingKey,upladerQueue .上传状态。完成);}上传请求.Queue.setItemStatus(这_curUploadingKey,upladerQueue .上传状态。完成);这个_ startUpload();} };函数getinstance(){ if(instance===null){ instance=new uploadEngine();}返回实例;}上传请求.engine=GetInstance();})(窗口。上传者队列);该对象比较简单主要提供一个奔跑以及setUrl方法,用于启动上传引擎,以及设置上传路径的功能。内部使用递归的方法把文件队列中的方法全部上传到服务端。使用上传项目进度通知外部上传的进度,使用上传状态已更改通知文件上传状态,以便更新用户界面.

uploaderApp.js中主要包括三个对象,一个是类似jquery的一个简单的jquery对象(App$)。主要用于绑定事件。一个是上传区域对象,是拖曳上传的窗口区域,另一个是入口对象上传人对象。主要用于初始化对象,对外部提供一个初始化方法,来初始化整个对象。

了解关于App$以及上传区域对象的代码请下载源代码,下面仅对上传人对象做简单的说明。

(函数(app){ var _ self;函数uploadermin(id){ this ._ id=id这个_ area=nullthis。uploaders=[];这个_URL='文件/上传程序;} uploadermain。prototype={ init : function(){ _ self=this;这个_ initArea();这个_ initQueueEng();},initQueueEng:函数(){上传队列.Engine.setUrl(这_ _ URL);上传者队列发动机。uploadstatuschanged=function(key,status){ if(status===uploader队列.上传状态。上传){ _自我. area.hideItemCancel(键);} else if (status===uploaderQueue .上传状态。完成){ _自我_area.completeItem(键);_self ._ area.showItemCancel(键);} }上传队列.发动机。uploaditem progress=function(key,e){ var progress=e . position/e . total;_self ._area.changeItemProgress(键,数学。回合(进度* 100));} },initarea : _ function(){ this ._area=新app.area(这. id);这个_区域。init();这个_区域。drop=function(e){ var key=uploader queue .排队。添加({ files : e . DataTransfer。文件});上传者队列发动机。run();返回键;}这个_区域。cancelage=function(key){ uploader queue .Queue.remove(键);} } };app.main=uploaderMain})(窗口。uploaderapp);在上传人对象,相当于各个对象之间的中介,主要就是做对象的初始化功能、以及对象之间相互调用。使各个对象之间相互协作完成整个模块的功能。对外提供一个初始化方法来初始化整个程序,在超文本标记语言页面中只需如下代码:

脚本类型=' text/JavaScript ' var main=new uploaderapp。main(' container ');主要的。init();/script以上代码就是创建一个入口对象,然后使用初始化方法来启动整个程序。

以上是对前端射流研究…的主要方法做的简单解释,如果想详细了解请下载源代码。下面简单看下后端节点端实现的主要代码。

在表达基础知识时,已经讲过在表达已经对文件上传功能做了完整的封装,当路由到行为时,文件已经完成上传只是文件上传到了一个临时目录,这个临时目录我们可以在app.js中配置的,配置方式如下:

app。使用(快递。正文解析器({ uploaddir : _ _ dirname '/public/temp ' });这样在文件上传后文件就存放在/公共/临时目录下,文件名也是表达通过一定的算法随机获取的。在我们写的行为中只需要把存在临时目录中的文件移动到服务端存放文件的目录下,然后删除临时目录下的文件即可。具体代码如下:

函数上传程序{ if (req.files!=' undefined '){控制台。目录(请求。文件);utils.mkDir().然后(函数(路径){ uploadFile(req,res,path,0);});} }函数上传文件(请求、资源、路径、索引){ var tempPath=req。文件。文件[索引].路径;var name=req.files.file[index].姓名;if(TempPATH){ var rename=promise。denodify(fs。重命名);重命名(临时路径,路径名)。然后(函数(){ var unlink=promise。denodify(fs。取消链接);取消链接(tempPath);}).然后(function(){ if(index==req。文件。文件。长度-1){ var RES={代码: 1,des: '上传成功' };发送;} else { uploadFile(req,res,path,index 1);} });}}2、实现效果

四、获取代码

代码下载地址://www .JB 51。net/jiao Ben/202117。超文本标记语言

版权声明:Nodejs express html5实现拖拽上传是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。