[ASP.NET] 如何利用Javascript分割檔案上傳至後端合併
最近研究了一下如何利用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的錯誤
如果各位有什麼問題,歡迎留言發問唷
參考:
[ASP.NET] 如何利用Javascript分割檔案上傳至後端合併的更多相关文章
- C#操作Word的+ CKEditor 輸出成Word文件(包含圖案上傳)
C#操作Word 参考博文: C#操作word类文件 https://www.cnblogs.com/walking/p/3571068.html C#中的Office操作专栏(21) http:// ...
- 利用javascript实现在圆周上匀速划动的动画效果
先看下效果:
- C# 選擇本機檔案並上傳
參考自:http://www.dotblogs.com.tw/puma/archive/2008/11/07/5910.aspxhttp://www.codeproject.com/Articles/ ...
- ASP利用xhEditor编辑器实现图片上传的功能。
本人这几天在做一个软件,无意中用到xhEditor在线编辑器,这个编辑器虽然看着比较简单,但功能非常强大,大家可以去官网上查看,废话不说了. 这篇文件主要是实现在ASP环境中利用xhEditor编辑器 ...
- 使用iTextSharp來合併PDF檔
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.I ...
- 利用XSD配合XSLT產出特定格式Word檔案 -摘自网络
利用類別產生XSD檔 產出XSD檔的目的在於提供Word樣板設計之資料框架 在此使用微軟提供之XML Schema Definition Tool (Xsd.exe)工具產生XSD檔 1. 定義類別 ...
- [ASP.NET] 檔案讀寫權限問題
今天遇到一個問題,環境如下: IIS Server: Server 2008 R2 沒加域 File Server: Server 2003 加域 當我的Web程序需要把位於File Server的一 ...
- 在 Server 端存取 Excel 檔案的利器:NPOI Library
转处 http://msdn.microsoft.com/zh-tw/ee818993.aspx Codeplex 軟體套件(Package)資訊 套件名稱 NPOI 作者 tonyqus, huse ...
- 如何在 Visual Studio 2012 控制 TFS 版控時要忽略哪些檔案
幾乎在任何一種版本控管的機制裡,都會遇到那些「不應該簽入到版本庫」的潛規則,以往我們在用 SVN 的時候,我就寫過幾篇文章要大家注意這點.最近都改用 TFS 做版控,因為大多使用 Visual Stu ...
随机推荐
- 判断DataTale中判断某个字段中包含某个数据
// <summary> /// 判断DataTale中判断某个字段中包含某个数据 /// </summary> /// <param name="dt&quo ...
- [Codeforces Round #516][Codeforces 1063C/1064E. Dwarves, Hats and Extrasensory Abilities]
题目链接:1063C - Dwarves, Hats and Extrasensory Abilities/1064E - Dwarves, Hats and Extrasensory Abiliti ...
- MS-UAP发布的UWP的个人隐私策略
我们十分重视您的隐私.本隐私声明解释了我们从您那里收集的个人数据内容以及我们将如何使用这些数据. 我们不收集任何与个人信息相关的数据,只收集与本UWP运行相关的数据,如: 产品使用数据:如每个页面的使 ...
- Javascript高级编程学习笔记(84)—— Canvas(1)基本用法
Canvas绘图 Canvas自HTML5引入后,由于其炫酷的效果成为HTML5新增功能中最受欢迎的部分 Canvas元素通过在页面中设定一个区域,然后就可以使用JS在其中绘制图形 <canva ...
- [Swift]LeetCode421. 数组中两个数的最大异或值 | Maximum XOR of Two Numbers in an Array
Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231. Find the maximum re ...
- [Swift]LeetCode474. 一和零 | Ones and Zeroes
In the computer world, use restricted resource you have to generate maximum benefit is what we alway ...
- AI - TensorFlow - 起步(Start)
01 - 基本的神经网络结构 输入端--->神经网络(黑盒)--->输出端 输入层:负责接收信息 隐藏层:对输入信息的加工处理 输出层:计算机对这个输入信息的认知 每一层点开都有它相应的内 ...
- java之Jvm学习--JVM运行机制
JVM启动流程 1.java虚拟机启动的命令是通过java +xxx(类名,这个类中要有main方法)或者javaw启动的. 2.执行命令后,系统第一步做的就是装载配置,会在当前路径中寻找jvm的co ...
- Mac 下生成keystore,并对apk进行签名
1.查看本机java环境 /usr/libexec/java_home -V 最后一行是Mac默认使用的jdk版本. 2.进入java的环境 /Library/Java/JavaVirtualMach ...
- 极速搭建RTMP直播流服务器+webapp (vue) 简单实现直播效果
在尝试使用webRTC实现webapp直播失败后,转移思路开始另外寻找可行的解决方案.在网页上尝试使用webRTC实现视频的直播与看直播,在谷歌浏览器以及safari浏览器上测试是可行的.但是基于基座 ...