分块上传时js如何指定文件上传到服务器指定文件夹?
【一个网工仔的悲喜交加:前端搞定了,后端求包养!】
各位道友好!俺是山西某高校网络工程专业的菜狗一枚,刚啃完《JavaScript从入门到住院》,就被导师按头要求搞个10G大文件上传系统。现在前端用Vue3+原生JS硬怼出了半成品,但后端还是个大坑啊!求各路神仙带带弟弟,或者收个关门弟子(管饭就行)!
💻 前端魔改代码(Vue3 + 原生JS兼容IE8版)
// FileUploader.js(兼容IE8的文件夹上传组件)
class OldSchoolUploader {
constructor(options) {
this.chunks = []; // 分片信息存储
this.fileMd5 = ''; // 文件唯一标识
this.isIE8 = !!window.ActiveXObject || "ActiveXObject" in window; // 检测IE8
this.isXinChuang = /Lotus|RedLotus|QAX/.test(navigator.userAgent); // 检测国产浏览器
// IE8专用XMLHttpRequest封装
this.getIE8XHR = () => {
try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { return new ActiveXObject("Microsoft.XMLHTTP"); }
};
// 计算文件MD5(IE8用文件名+大小当伪MD5)
this.calculateMD5 = (file, callback) => {
if (this.isIE8) {
callback(`${file.name}-${file.size}-${Date.now()}`);
} else {
// 正常MD5计算(此处省略200行crypto-js代码)
console.log("正常浏览器MD5计算中...");
}
};
}
// 文件夹上传(递归遍历+FormData魔改)
uploadFolder(folder, parentPath = '') {
const files = [];
const dirReader = folder.createReader();
dirReader.readEntries(entries => {
entries.forEach(entry => {
if (entry.isFile) {
entry.file(file => {
files.push({
path: `${parentPath}/${entry.name}`,
file
});
});
} else {
this.uploadFolder(entry, `${parentPath}/${entry.name}`);
}
});
// 国产浏览器降级处理
if (this.isXinChuang) {
setTimeout(() => this.processFiles(files), 100);
} else {
Promise.all(files).then(() => this.processFiles(files));
}
});
}
// 断点续传进度保存(兼容IE8的localStorage降级方案)
saveProgress(fileMd5, progress) {
if (window.localStorage) {
localStorage.setItem(`upload_${fileMd5}`, JSON.stringify(progress));
} else if (document.documentElement.addBehavior) {
// IE8及以下用userData存储
const storage = document.createElement('div');
storage.addBehavior('#default#userData');
storage.setAttribute('progress', JSON.stringify(progress));
storage.save(`upload_${fileMd5}`);
}
}
}
// Vue3组件中使用示例
export default {
methods: {
handleFolderUpload(event) {
const folderInput = event.target;
if (folderInput.files && folderInput.files[0]) {
const folder = folderInput.files[0].webkitRelativePath
? folderInput.files[0] // Chrome
: { // IE/Edge模拟文件夹
name: 'fake_folder',
createReader: () => ({
readEntries: callback => {
const entries = Array.from(folderInput.files).map(file => ({
isFile: true,
name: file.name,
file: () => new Promise(resolve => resolve(file))
}));
callback(entries);
}
})
};
const uploader = new OldSchoolUploader();
uploader.uploadFolder(folder);
}
}
}
}
🎯 血泪经验总结
-
浏览器兼容性:
- IE8用
ActiveXObject替代fetch - 国产浏览器(如龙芯)需禁用某些现代API
- 文件路径统一用
/避免转义问题
- IE8用
-
断点续传秘籍:
// 本地存储进度(兼容IE8) const saveProgress = (fileMd5, progress) => { if (window.localStorage) { localStorage.setItem(`upload_${fileMd5}`, JSON.stringify(progress)); } else { // IE8降级方案 document.cookie = `upload_${fileMd5}=${encodeURIComponent(JSON.stringify(progress))};path=/`; } }; -
加密传输方案:
- 前端用
CryptoJS加密(需引入polyfill支持IE8) - 后端计划用Python的
cryptography库解密 - 传输走HTTPS(本地用自签名证书)
- 前端用
🙏 江湖救急
现诚征各路大侠:
- 加入QQ群:374992201(进群领1-99元红包,推荐项目拿50%提成!)
- 求后端师傅收留(Python/Java/Go都行,可签卖身契)
- 需要完整项目代码的兄弟,群里每天晚上8点准时发车!
(附:导师说项目要是能过,请群主吃平遥牛肉管够!🐂)
💡 群内福利
- 免费提供IE8兼容性测试工具包
- 每周三晚代码接诊(大佬在线改bug)
- 共享国产浏览器虚拟机环境(龙芯/红莲花/奇安信)
PS:群里还有"从0到1搭建后端"系列教程,包括:
- Python Flask/Django极速入门
- MySQL分片存储方案设计
- CentOS部署全流程手把手教学
(悄悄说:群文件里有《如何让导师感动到哭的答辩技巧》.pdf)🤫
将组件复制到项目中
示例中已经包含此目录

引入组件

配置接口地址
接口地址分别对应:文件初始化,文件数据上传,文件进度,文件上传完毕,文件删除,文件夹初始化,文件夹删除,文件列表
参考:http://www.ncmem.com/doc/view.aspx?id=e1f49f3e1d4742e19135e00bd41fa3de

处理事件

启动测试

启动成功

效果

数据库

效果预览
文件上传

文件刷新续传
支持离线保存文件进度,在关闭浏览器,刷新浏览器后进行不丢失,仍然能够继续上传

文件夹上传
支持上传文件夹并保留层级结构,同样支持进度信息离线保存,刷新页面,关闭页面,重启系统不丢失上传进度。

下载示例
点击下载完整示例
本文地址:https://www.yitenyun.com/4665.html
下一篇:AAA服务器技术







