首頁  >  文章  >  web前端  >  H5+WebSocket多檔案同時上傳

H5+WebSocket多檔案同時上傳

php中世界最好的语言
php中世界最好的语言原創
2018-03-26 14:01:452627瀏覽

這次帶給大家H5+WebSocket多檔案同時上傳,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(&#39;rounded&#39;);
        }
 
        function onDragLeave(e) {
            e.stopPropagation();
            e.preventDefault();
            $(dropbox).removeClass(&#39;rounded&#39;);
        }
 
        function onDrop(e) {
            e.stopPropagation();
            e.preventDefault();
            $(dropbox).removeClass(&#39;rounded&#39;);
            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) {
            $(&#39;#p_&#39; + file.ID).progressbar({ value: (file.PageIndex / file.Pages) * 100,
                text: file.FileName + &#39;[&#39; + file.UploadBytes + &#39;/&#39; + file.Size + &#39;]&#39;
            });
        }

C#服務端

借助Beetle對websocket的支援對應服務端的實作就非常簡單了

/// <summary>
    /// Copyright © henryfan 2012        
    ///CreateTime:  2012/12/14 21:13:34
    /// </summary>
    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  ######相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章! ######推薦閱讀:#########spring mvc+localResizeIMG實作H5端圖片壓縮上傳###############H5表單驗證有哪些方法# ##############H5實作旋轉立體魔術方塊##########

以上是H5+WebSocket多檔案同時上傳的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn