博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[ASP.NET] 如何利用Javascript分割檔案上傳至後端合併
阅读量:6191 次
发布时间:2019-06-21

本文共 3802 字,大约阅读时间需要 12 分钟。

最近研究了一下如何利用javascript進行檔案分割上傳並且透過後端。特地記錄一下相關的用法

先寫限制跟本篇的一些陷阱

1.就是瀏覽器的支援了 因為本篇有用到blob跟webworker

在ie中需要最少10版以上才有支援以下的方法喔!

2.因為我這是簡單的測試,所以我是將檔案存放在Session當中,實際要使用的話。應該會是將檔案分割存放在檔案系統中

廢話就不多說,我們先來看js端的程式碼

self.onmessage = function (e) {    ////web worker started    var blob = e.data.file; //取得檔案內容    const SPLIT_BYTES = 100 * 1024; //檔案以每100KB做切割    const SIZE = blob.size; //檔案的大小    var start = 0; //位元組數的開頭    var end = SPLIT_BYTES; //位元組數的結束    var count = SIZE % SPLIT_BYTES == 0 ? SIZE / SPLIT_BYTES : Math.floor(SIZE / SPLIT_BYTES) + 1;    //上述為計算一共會切出幾份檔案    var intIdentifier = 1;    var completed = 0;    var xhr = new self.XMLHttpRequest();    xhr.onload = function () {        completed++; //完成上傳的計數器        if (completed === count) {            //當最後一個檔案成功上傳時,通知後端做檔案處理            uploadComplete(e.data.pid, blob.name);        }    }    //這裡代表當檔案可以進行切割時,就利用切割進行檔案上傳    if(SIZE>SPLIT_BYTES){        for (var i = 1; i <= count; i++) {            var chunk = blob.slice(start, end); //##這裡需要特別注意的是,我們利用slice來將檔案的位元組數做"分段(切割)"讀取            var url = '/Oberto/Manager/Home/fileUpload/' + intIdentifier + '?name=' + e.data.pid + "&filename=" + blob.name +"&cache="+Date.now();            xhr.open('POST', url, false);            xhr.setRequestHeader('Content-Type', 'application/octet-stream');            xhr.send(chunk);            //因為我們是"分段(切割)"做處理,所以我們的start與end要跟著做移動            start = end;             end = start + SPLIT_BYTES;            intIdentifier++;        }    } else {        //這裡就是一般的檔案上傳動作了        var url = '/Oberto/Manager/Home/fileUpload/' + intIdentifier + '?name=' + e.data.pid + "&filename=" + blob.name + "&cache=" + Date.now();        xhr.open('POST', url, false);        xhr.setRequestHeader('Content-Type', 'application/octet-stream');        xhr.send(blob.slice(start, SIZE));    }   //這裡則是當分割的檔案上傳完成後,要通知後端處理    function uploadComplete(id, name) {        var url1 = '/Oberto/Manager/Home/UploadComplete?id=' + id + "&filename=" + name + "&semesterID=" + e.data.semesterID + "&cache=" + Date.now();;        var xhr1 = new self.XMLHttpRequest();        xhr1.onload = function (e) {            var result = JSON.parse(xhr1.response);            self.postMessage(result);        }        xhr1.open('POST', url1, true);        xhr1.send(null);    }}

 

以上是我webwork程式所執行的內容,比較需要注意的部分是在於你需要利用blob.slice進行檔案分段的處理。

而我因為方便,將最後完成處理與分段上傳的動作分為兩個。因此在後端也會有相對應的程式碼

[HttpPost]        [ValidateInput(false)]        public string fileUpload(int id)        {            //這裡依照傳送過來的檔案大小,建立對應的byte陣列進行接收            byte[] chunk = new byte[Request.InputStream.Length];            //這裡就將檔案內容存入剛剛建立的byte陣列裡            Request.InputStream.Read(chunk, 0, Convert.ToInt32(Request.InputStream.Length));            if (Session["tempFiles"] == null)            {                Session["tempFiles"] = chunk;                //因為我這裡是利用Session當示範,所以利用Session進行存放            }            else            {                //當已經接收過檔案時,這裡就額外建立一個合併用的byte                //然後利用BlockCopy做合併的動作                byte[] tempChunk = Session["tempFiles"] as byte[];                byte[] newChunk = new byte[tempChunk.Length + chunk.Length];                                Buffer.BlockCopy(tempChunk, 0, newChunk, 0, tempChunk.Length);                Buffer.BlockCopy(chunk, 0, newChunk,tempChunk.Length, chunk.Length);                Session["tempFiles"] = newChunk;            }            return "InComplete";        }

 

以上就是後端如何接收與處理分割後的檔案。至於完成後的處理,就看各位如何做了

我的最終完成後的處理其實就很簡單的將我Session存放的內容轉換成檔案放置到我的伺服器目錄下

這篇算是比較完整的從前端到後端整個分割檔案處理的流程

這裡有一點要注意的是,平常我們用XMLHttpRequest的時候做資料POST或GET 都會用非同步的方式  e.g.  xhr1.open( 'POST', url1, true);

而因為都用了Web Wroker了(也就是建一個新的執行緒,所以就算用同步也不會lock住我們目前頁面的主執行緒) 

這裡就可以改成同步,否則在非同步的情況下,透過FIDDLER會抓到Content-Length dismatch的錯誤

如果各位有什麼問題,歡迎留言發問唷

參考:

转载于:https://www.cnblogs.com/KingJaja/p/5479728.html

你可能感兴趣的文章
Safari/Chrome中placeholder属性实现不完整
查看>>
转载 - 18个最佳代码编辑器/IDE推荐
查看>>
用Opencv保存视频文件avi(转)
查看>>
几条常见的数据库分页 SQL 语句
查看>>
XCode最佳实践之最佳数据类型
查看>>
asp.net 中sender 的理解
查看>>
RSS文章订阅及生成RSS格式的xml
查看>>
你自认为理解了JavaScript?
查看>>
读《程序员的SQL金典》[4]--SQL调优
查看>>
死锁产生的原因及四个必要条件
查看>>
CSS3----background:-webkit-gradient()渐变效果
查看>>
RTP协议分析
查看>>
前后端分离了,然后呢?(转)
查看>>
自定义控件:滑动开关按钮
查看>>
js修改后没反应-看看是不是取的缓存
查看>>
【iCore3 双核心板_ uC/OS-III】例程十一:任务消息队列
查看>>
C#的delegate简单练习
查看>>
【301】IDL与C#混合编程
查看>>
分治法应用之一——Strassen矩阵乘法(转)
查看>>
linux-diff命令
查看>>