H5+WebSocket多文件同时上传-
在传统的HTTP利用上传文件想要同时上传多个文件并查看上传进度是一件很费事的事情,固然此刻也有一些基于SWF的文件上传组件供给这种的便捷性.到了HTML5下对文件的读取和上传的控制方面就非常灵便,HTML5供给一系列的AIP进行文件读取,包含计取文件某一块的内容也非常利便,联合Websocket进行文件的传输就变得更加利便和灵便.下面通过运用HTML5联合websocet简略地实现多文件同时上传利用.
实现功能
大约预览一下需要做的功能:
主要功能是会员可以直接把文件夹的文件直接拖放到网页中,并进行上传,在上传的历程中显示上传进度信息.
FileInfo类封装
为了利便读取文件信息,在原有File的根基封装了一个简略文件信息读取的对象类.
function FileInfo(file, pagesize) { this.Size = file.size; this.File = file; this.FileType = file.type; this.FileName = file.name; this.PageSize = pagesize; this.PageIndex = 0; this.Pages = 0; this.UploadError = null; this.UploadProcess = null; this.DataBuffer = null; this.UploadBytes = 0; this.ID = Math.floor(Math.random() * 0x10000).toString(16); this.LoadCallBack = null; if (Math.floor(this.Size % this.PageSize) > 0) { this.Pages = Math.floor((this.Size / this.PageSize)) + 1; } else { this.Pages = Math.floor(this.Size / this.PageSize); } } FileInfo.prototype.Reset = function () { this.PageIndex = 0; this.UploadBytes = 0; } FileInfo.prototype.toBase64String = function () { var binary = '' var bytes = new Uint8Array(this.DataBuffer) var len = bytes.byteLength; for (var i = 0; i < len; i++) { binary += String.fromCharCode(bytes[i]) } return window.btoa(binary); } FileInfo.prototype.OnLoadData = function (evt) { var obj = evt.target["tag"]; if (evt.target.readyState == FileReader.DONE) { obj.DataBuffer = evt.target.result; if (obj.LoadCallBack != null) obj.LoadCallBack(obj); } else { if (obj.UploadError != null) obj.UploadError(fi, evt.target.error); } } FileInfo.prototype.Load = function (completed) { this.LoadCallBack = completed; if (this.filereader == null || this.filereader == undefined) this.filereader = new FileReader(); var reader = this.filereader; reader["tag"] = this; reader.onloadend = this.OnLoadData; var count = this.Size - this.PageIndex * this.PageSize; if (count > this.PageSize) count = this.PageSize; this.UploadBytes += count; var blob = this.File.slice(this.PageIndex * this.PageSize, this.PageIndex * this.PageSize + count); reader.readAsArrayBuffer(blob); }; FileInfo.prototype.OnUploadData = function (file) { var channel = file._channel; var url = file._url; channel.Send({ url: url, parameters: { FileID: file.ID, PageIndex: file.PageIndex, Pages: file.Pages, Base64Data: file.toBase64String()} }, function (result) { if (result.status == null || result.status == undefined) { file.PageIndex++; if (file.UploadProcess != null) file.UploadProcess(file); if (file.PageIndex < file.Pages) { file.Load(file.OnUploadData); } } else { if (file.UploadError != null) file.UploadError(file, data.status); } }); } FileInfo.prototype.Upload = function (channel, url) { var fi = this; channel.Send({ url: url, parameters: { FileName: fi.FileName, Size: fi.Size, FileID: fi.ID} }, function (result) { if (result.status == null || result.status == undefined) { fi._channel = channel; fi._url = result.data; fi.Load(fi.OnUploadData); } else { if (file.UploadError != null) file.UploadError(fi, result.status); } }); }
类的处置很简略,通过file初始化并指定分块大小来实始化一些文件信息,如页数目页大小等.固然最重要还封装文件对应的Upload办法,用于把文件块信息打包成base64信息通过Websocket的方式发送到办事器.
文件拖放
在HTML5中承受系统文件拖放进来并不需要做复杂的事情,只需要针对容器元素绑定相干事件即可.
function onDragEnter(e) { e.stopPropagation(); e.preventDefault(); } function onDragOver(e) { e.stopPropagation(); e.preventDefault(); $(dropbox).addClass('rounded'); } function onDragLeave(e) { e.stopPropagation(); e.preventDefault(); $(dropbox).removeClass('rounded'); } function onDrop(e) { e.stopPropagation(); e.preventDefault(); $(dropbox).removeClass('rounded'); var readFileSize = 0; var files = e.dataTransfer.files; if (files.length > 0) { onFileOpen(files); } }
只需要在onDrop历程中猎取相干拖放文件即可,这些可能通过一些HTML5的教程可以得到帮忙。
这时候只需要针对选中的文件构建相干FileInfo对象,并调取上传办法即可.
function onFileOpen(files) { if (files.length > 0) { for (var i = 0; i < files.length; i++) { var info = new FileInfo(files[i], 32768); uploads.push(info); info.UploadProcess = onUploadProcess; addUploadItem(info); } } }
通过UploadProcess事件对上传文件进度信息进行一个设定更新
function onUploadProcess(file) { $('#p_' + file.ID).progressbar({ value: (file.PageIndex / file.Pages) * 100, text: file.FileName + '[' + file.UploadBytes + '/' + file.Size + ']' }); }
C#办事端
借助于Beetle对websocket的支撑对应办事端的实现就非常简略了
////// Copyright ? henryfan 2012 ///CreateTime: 2012/12/14 21:13:34 /// public class Handler { public void UploadPackage(string FileID, int PageIndex, int Pages, string Base64Data) { Console.WriteLine("FileID:{2},PageIndex:{0} Pages:{1} DataLength:{3}", PageIndex, Pages, FileID,Base64Data.Length); } public string UploadFile(string FileID, string FileName, long Size) { Console.WriteLine("FileID:{2},FileName:{0} Size:{1}", FileName, Size, FileID); return "Handler.UploadPackage"; } }
办事端办法有两个一个是上传文件要求,和一个上传文件块接收办法.
总结
只需要以上简略的代码就能实现多文件同时上传功能,在这采纳json来处置上传的信息,所以文件流要进行一个base64的编码处置,因为websocket阅读提交的数据个别都有MASK处置再加上base64那损耗相对来说比拼重,现实上websocket有供给流的数据包格局(arraybuffer);固然这种处置在操纵上就没有json来得利便简略.
下载代码:WebSocketUpload.rar
信赖看了本案牍例你已经把握了办法,更多出色请关注 百分百源码网 其它相干文章!
举荐浏览:
spring mvc+localResizeIMG实现H5端图片紧缩上传
H5表单验证是什么办法
H5实现扭转立体魔方
以上就是H5+WebSocket多文件同时上传的细致内容,更多请关注 百分百源码网 其它相干文章!