欢迎光临
我们一直在努力

分块上传时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)
    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)🤫

    将组件复制到项目中

    示例中已经包含此目录 image

    引入组件

    image

    配置接口地址

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

    处理事件

    image

    启动测试

    image

    启动成功

    image

    效果

    image

    数据库

    image

    效果预览

    文件上传

    文件上传

    文件刷新续传

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

    文件夹上传

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

    下载示例

    点击下载完整示例

    赞(0)
    未经允许不得转载:171主机测评 » 分块上传时js如何指定文件上传到服务器指定文件夹?
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址