前台代码:
<form id="uploadForm" enctype="multipart/form-data">
<input type="file" name="file" id="fileInput" multiple />
<button type="button" onclick="onuploadForm()">上传</button>
</form>
<div id="progressBar" style="background-color: lightgray; height: 20px;"></div>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
function onuploadForm() {
var file = $('#fileInput').get(0).files[0];
var chunkSize = 1024 * 1024; // 1MB
var fileSize = file.size;
var totalChunks = Math.ceil(fileSize / chunkSize);
var currentChunk = 0;
var uploadChunk = function () {
var start = currentChunk * chunkSize;
var end = Math.min(start + chunkSize, fileSize);
var formData = new FormData();
formData.append('file', file.slice(start, end));
formData.append('totalChunks', totalChunks);
formData.append('currentChunk', currentChunk);
$.ajax({
url: '/File/ProcessChunk',
type: 'POST',
data: formData,
contentType: false,
processData: false,
beforeSend: function () {
// 在发送请求之前,初始化一些相关操作
$('#progressBar').width('0%');
$('#progressBar').text('0%');
},
uploadProgress: function (event, position, total, percentComplete) {
// 在上传过程中更新进度条
var percent = percentComplete.toFixed(2) + '%';
$('#progressBar').width(percent);
$('#progressBar').text(percent);
},
success: function (result) {
currentChunk++;
if (currentChunk < totalChunks) {
uploadChunk();
} else {
console.log('文件上传成功');
mergeChunks(result.fileName, result.totalChunks);
}
},
error: function (error) {
console.log(error);
}
});
};
uploadChunk();
}
// 合并切片请求
function mergeChunks(fileName, totalChunks) {
$.ajax({
type: "POST",
url: "/File/MergeChunks",
data: { fileName: fileName, totalChunks: totalChunks },
success: function (result) {
console.log(result);
if (result.success) {
alert('文件上传并合并成功');
} else {
alert('合并切片失败');
}
},
error: function () {
alert('合并切片请求错误');
}
});
}
</script>
后台mvc代码:
[HttpPost]
public IActionResult ProcessChunk(IFormFile file, int totalChunks, int currentChunk)
{
var uploadsFolderPath = Path.Combine(Directory.GetCurrentDirectory(), "Uploads");
var fileName = Path.GetFileName(file.FileName);
var filePath = Path.Combine(uploadsFolderPath, fileName + $".part{currentChunk}");
using (var stream = new FileStream(filePath, FileMode.Create))
{
file.CopyTo(stream);
}
return Ok();
}
[HttpPost]
public IActionResult MergeChunks(string fileName, int totalChunks)
{
var uploadsFolderPath = Path.Combine(Directory.GetCurrentDirectory(), "Uploads");
var mergedFilePath = Path.Combine(uploadsFolderPath, fileName);
using (var mergedFileStream = new FileStream(mergedFilePath, FileMode.Create))
{
for (int i = 0; i < totalChunks; i++)
{
var partFilePath = Path.Combine(uploadsFolderPath, fileName + $".part{i}");
using (var partFileStream = new FileStream(partFilePath, FileMode.Open))
{
partFileStream.CopyTo(mergedFileStream);
}
System.IO.File.Delete(partFilePath);
}
}
return Ok();
}
要是对进度条不满意 可使用下面的:
<div class="progress-bar" style="display:none">
<div class="progress"></div>
</div>
<style>
.progress-bar {
width: 100%;
height: 20px;
background-color: #f0f0f0;
border-radius: 10px;
overflow: hidden;
position: relative;
}
.progress {
height: 100%;
background-color: #4caf50;
width: 0;
transition: width 0.5s ease-in-out;
position: absolute;
top: 0;
left: 0;
}
</style>
至于对进度条赋值:
$('.progress').css('width', percentComplete + '%');
建议:js不要使用alert 弹框 避免影响进度条加载进度 优先考虑使用如layui 中下面这种方式
layer.msg('文件上传并合并成功', { icon: 1 });