最近研究了一下如何利用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, , 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, , newChunk, , tempChunk.Length);
Buffer.BlockCopy(chunk, , 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的錯誤

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

參考:

http://stackoverflow.com/questions/20212851/slice-large-file-into-chunks-and-upload-using-ajax-and-html5-filereader

[ASP.NET] 如何利用Javascript分割檔案上傳至後端合併的更多相关文章

  1. C#操作Word的+ CKEditor 輸出成Word文件(包含圖案上傳)

    C#操作Word 参考博文: C#操作word类文件 https://www.cnblogs.com/walking/p/3571068.html C#中的Office操作专栏(21) http:// ...

  2. 利用javascript实现在圆周上匀速划动的动画效果

    先看下效果:          

  3. C# 選擇本機檔案並上傳

    參考自:http://www.dotblogs.com.tw/puma/archive/2008/11/07/5910.aspxhttp://www.codeproject.com/Articles/ ...

  4. ASP利用xhEditor编辑器实现图片上传的功能。

    本人这几天在做一个软件,无意中用到xhEditor在线编辑器,这个编辑器虽然看着比较简单,但功能非常强大,大家可以去官网上查看,废话不说了. 这篇文件主要是实现在ASP环境中利用xhEditor编辑器 ...

  5. 使用iTextSharp來合併PDF檔

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.I ...

  6. 利用XSD配合XSLT產出特定格式Word檔案 -摘自网络

    利用類別產生XSD檔 產出XSD檔的目的在於提供Word樣板設計之資料框架 在此使用微軟提供之XML Schema Definition Tool (Xsd.exe)工具產生XSD檔 1. 定義類別 ...

  7. [ASP.NET] 檔案讀寫權限問題

    今天遇到一個問題,環境如下: IIS Server: Server 2008 R2 沒加域 File Server: Server 2003 加域 當我的Web程序需要把位於File Server的一 ...

  8. 在 Server 端存取 Excel 檔案的利器:NPOI Library

    转处 http://msdn.microsoft.com/zh-tw/ee818993.aspx Codeplex 軟體套件(Package)資訊 套件名稱 NPOI 作者 tonyqus, huse ...

  9. 如何在 Visual Studio 2012 控制 TFS 版控時要忽略哪些檔案

    幾乎在任何一種版本控管的機制裡,都會遇到那些「不應該簽入到版本庫」的潛規則,以往我們在用 SVN 的時候,我就寫過幾篇文章要大家注意這點.最近都改用 TFS 做版控,因為大多使用 Visual Stu ...

随机推荐

  1. CefSharp Cookie独立 GetGlobalCookieManager

    可以实现:  登陆多个京东站点,而京东各个账号互不影响. 可以完全实现Cookie独立,Cache独立. Demo用VS2017开发,C# ,NET4.5 没错,稍加改造就可以用来刷单.有Demo,有 ...

  2. h5唤起APP并检查是否成功

    // 检查app是否打开 function checkOpen(cb) { const clickTime = +(new Date()); function check(elsTime) { if ...

  3. 在Centos中安装mysql

    下载mysql 这里是通过安装Yum源rpm包的方式安装,所以第一步是先下载rpm包 1.打开Mysql官网 https://www.mysql.com/, 点击如图选中的按钮 点击如图框选的按钮 把 ...

  4. (一) sublime安装和使用

    1  下载安装sublime 可以破解也可以不破解 2 html基础架子自动生成插件Emmet的安装 3 Emmet 安装失败解决 4 快捷键设置和汇总 4 其他sublime插件汇总

  5. 12.JavaScript字符串方法

    JS字符串常用方法总结 动态方法:1.str.charAt(index);  返回子字符串,index为字符串下标,index取值范围[0,str.length-1] 动态方法:2.str.charC ...

  6. window server 2008 安装Oracle10g

    oracle安装都大同小异. 开始安装步骤 输入完之后点击下一步 这时候稍等一会儿. 这时候也要稍等一会儿. 直接安装. 设置口令管理,设置SCOTT的密码为tiger就好了. 这时候稍等一会儿. o ...

  7. Python入门(青铜篇)

    一.定义变量 print('hello world \n') 定义变量name='单宝梁' #定义字符串一定加‘’age=28 引号使用words="i'm 单宝梁" #字符串里有 ...

  8. Mesos源码分析(8): Mesos-Slave的初始化

      Mesos-Slave的初始化在文件src/slave/slave.cpp里面     首先初始化资源预估器   初始化attributes   初始化hostname     初始化status ...

  9. ASP.NET Core Web App应用第三方Bootstrap模板

    引言 作为后端开发来说,前端表示玩不转,我们一般会选择套用一些开源的Bootstrap 模板主题来进行前端设计.那如何套用呢?今天就简单创建一个ASP.NET Core Web MVC 模板项目为例, ...

  10. 高级Java面试总结2

    1. JVM结构原理.GC工作机制详解 答:具体参照:JVM结构.GC工作机制详解     ,说到GC,记住两点:1.GC是负责回收所有无任何引用对象的内存空间. 注意:垃圾回收回收的是无任何引用的对 ...