檔案太大無法一次上傳,切分成小塊後再分次上傳到Server
upload large files in ASP.NET Core
divide the large file be chunks and upload
HTML部分
<!--沒錯就是這麼簡單-->
<input type="file" id="bigfile" />
<script src="~/lib/jquery/dist/jquery.min.js"></script>
JS部分
$(document).on("change", "#bigfile", function () {
uploadFile($("#bigfile")[0].files[0]);
});
function uploadFile(file) {
//把檔案切塊(file chunk)每塊最大不超過100KB
var maxFileSizeKB = 100;
var fileChunks = [];
var bufferChunkSizeInBytes = maxFileSizeKB * (1024);
var currentStreamPosition = 0;
var endPosition = bufferChunkSizeInBytes;
var size = file.size;
while (currentStreamPosition < size) {
fileChunks.push(file.slice(currentStreamPosition, endPosition));
currentStreamPosition = endPosition;
endPosition = currentStreamPosition + bufferChunkSizeInBytes;
}
//產生Timestamp當不重複的隨機檔名
var timestamp = new Date().getTime()
var fileName = timestamp + "_" + file.name;
uploadFileChunk(fileChunks, fileName, 1, fileChunks.length);
}
function uploadFileChunk(fileChunks, fileName, currentPart, totalPart) {
var formData = new FormData();
formData.append('file', fileChunks[currentPart - 1], fileName);
$.ajax({
type: "POST",
url: '/UploadChunk/UploadFileChunks',
contentType: false,
processData: false,
data: formData,
success: function (data) {
if (totalPart >= currentPart) {
console.log("uploading file part no: " + currentPart, " out of " + totalPart);
if (data.status == true) {
if (totalPart == currentPart) {
//Whole file uploaded
console.log("whole file uploaded successfully");
} else {
//Show uploading progress
uploadFileChunk(fileChunks, fileName, currentPart + 1, totalPart);
}
} else {
//retry message to upload rest of the file
console.log("failed to upload file part no: " + currentPart);
}
}
},
error: function () {
//retry message to upload rest of the file
console("error to upload file part no: " + currentPart);
}
});
}
Controller部分
using Microsoft.AspNetCore.Mvc;
namespace WebUploadDemo.Controllers
{
public class UploadChunkController : Controller
{
private readonly IWebHostEnvironment _env;
public UploadChunkController(IWebHostEnvironment env)
{
_env = env;
}
public JsonResult UploadFileChunks()
{
var files = Request.Form.Files;
if (files.Count > 0)
{
try
{
var file = files.First();
string filePath = Path.Combine(GetUploadPath(), file.FileName);
using (var ms = new MemoryStream())
{
file.CopyTo(ms);
var fileBytes = ms.ToArray();
using (FileStream fs = new FileStream(filePath, FileMode.Append))
{
var bytes = fileBytes;
fs.Write(bytes, 0, bytes.Length);
}
}
return Json(new { status = true });
}
catch (Exception ex)
{
return Json(new { status = false, message = ex.Message });
}
}
return Json(new { status = false });
}
private string GetUploadPath()
{
string rootPath = Path.Combine(_env.WebRootPath, "UploadedFiles");
if (!Directory.Exists(rootPath))
{
Directory.CreateDirectory(rootPath);
}
return rootPath;
}
}
}
參考資料:https://www.dotnetbull.com/2018/09/uploading-large-file-chunks-javascript-ajax-mvc-dotnet.html