您现在的位置是:网站首页> 编程资料编程资料
JavaScript进阶之前端文件上传和下载示例详解_javascript技巧_
2023-05-24
415人已围观
简介 JavaScript进阶之前端文件上传和下载示例详解_javascript技巧_
文件下载
1.通过a标签点击直接下载
download属性标识文件需要下载且下载名称为test
如果有 Content-Disposition 响应头,则不需要设置download属性就能下载,文件名在响应头里面由后端控制
此方法有同源和请求headers鉴权的问题
2.open或location.href
window.open('xxx.zip'); location.href = 'xxx.zip'; 需要注意 url 长度和编码问题
不能直接下载浏览器默认预览的文件,如txt、图片
3.Blob和Base64
function downloadFile(res, Filename) { // res为接口返回数据,在请求接口的时候可进行鉴权 if (!res) return; // IE及IE内核浏览器 if ("msSaveOrOpenBlob" in navigator) { navigator.msSaveOrOpenBlob(res, name); return; } const url = URL.createObjectURL(new Blob([res])); // const fileReader = new FileReader(); 使用 Base64 编码生成 // fileReader.readAsDataURL(res); // fileReader.onload = function() { ...此处逻辑和下面创建a标签并释放代码一致,可从fileReader.result获取href值...} const a = document.createElement("a"); a.style.display = "none"; a.href = url; a.download = Filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); // 释放blob对象 } 注意 请求发送的时候注明 responseType = "blob",如无设置则需要 new Blob的时候传入第二个参数,如
new Blob([res], { type: xhr.getResponseHeader("Content-Type") });
此方法可以解决请求headers鉴权和下载浏览器默认直接预览的文件,并得知下载进度
文件上传
文件上传思路

File文件
- MDN描述

上传单个文件-客户端
type属性file:用户选择文件accept属性:规定选择文件的类型

上传进度:0
上传文件-服务端
- 客户端使用form-data传递,服务端使用相同方式接受解析
- 使用 multer 库处理 multipart/form-data

const app = express(); // 上传成功后返回URL地址 const resourceUrl = `http://127.0.0.1:${port}/`; // 存储文件目录 const uploadDIr = path.join(__dirname, "/upload"); // destination 设置资源保存路径,filename 设置资源名称 const storage = multer.diskStorage({ destination: async function (_req, _file, cb) { cb(null, uploadDIr); }, filename: function (_req, file, cb) { // 设置文件名 cb(null, `${file.originalname}`); }, }); const multerUpload = multer({ storage }); //设置静态访问目录 app.use(express.static(uploadDIr)); app.post("/upload", multerUpload.any(), function (req, res, _next) { // req.file 是 `avatar` 文件的信息 let urls = []; //获取所有已上传的文件 const files = req.files; if (files && files.length > 0) { //遍历生成url 集合返回给客户端 urls = files.map((item, _key) => { return resourceUrl + item.originalname; }); } return res.json({ REV: true, DATA: { url: urls, }, MSG: "成功", }); }); 多文件上传-客户端
- input属性:
multiple是否允许多个值(相关类型email、file)
上传进度:0
大文件上传-客户端

上传进度:0
fileUtils
// 文件分片 function handleFileChunk(file, chunkSize) { const fileChunkList = []; // 索引值 let curIndex = 0; while (curIndex < file.size) { // 最后一个切片以实际结束大小为准。 const endIndex = curIndex + chunkSize < file.size ? curIndex + chunkSize : file.size; // 截取当前切片大小 const curFileChunkFile = file.slice(curIndex, endIndex); // 更新当前索引 curIndex += chunkSize; fileChunkList.push({ file: curFileChunkFile }); } return fileChunkList; } //设置默认切片大小为5M const DefaultChunkSize = 5 * 1024 * 1024; const start = async function (bigFile) { // 生成多个切片 const fileList = handleFileChunk(bigFile, DefaultChunkSize); // 获取整个大文件的内容hash,方便实现秒传 // const containerHash = await getFileHash(fileList); const containerHash = await getFileHash2(bigFile); // 给每个切片添加辅助内容信息 const chunksInfo = fileList.map(({ file }, index) => ({ // 整个文件hash fileHash: containerHash, // 当前切片的hash hash: containerHash + "-" + index, // 当前是第几个切片 index, // 文件个数 fileCount: fileList.length, // 切片内容 chunk: file, // 文件总体大小 totalSize: bigFile.size, // 单个文件大小 size: file.size, })); //上传所有文件 uploadChunks(chunksInfo, bigFile.name); }; /** * * 获取全部文件内容hash * @param {any} fileList */ async function getFileHash(fileList) { console.time("filehash"); const spark = new SparkMD5.ArrayBuffer(); // 获取全部内容 const result = fileList.map((item, key) => { return getFileContent(item.file); }); try { const contentList = await Promise.all(result); for (let i = 0; i < contentList.length; i++) { spark.append(contentList[i]); } // 生成指纹 const res = spark.end(); console.timeEnd("filehash"); return res; } catch (e) { console.log(e); } } /** * * 获取全部文件内容hash * @param {any} fileList */ as
相关内容
- react框架next.js学习之API 路由篇详解_React_
- React实现多个场景下鼠标跟随提示框详解_React_
- TypeScript的类型指令单行注释详解_JavaScript_
- Vue组件间传值的实现解析_vue.js_
- Vue插槽的作用_vue.js_
- Vue路由模式中的hash和history模式详细介绍_vue.js_
- Vue路由元信息与懒加载和模块拆分详细介绍_vue.js_
- node里的filesystem模块文件读写操作详解_node.js_
- 微信小程序实现事件传参与数据同步流程详解_javascript技巧_
- vue项目实例中用query传参如何实现跳转效果_vue.js_
点击排行
本栏推荐
