大文件上传

234 阅读1分钟

切片上传

前端(客户端)

//获取文件 <input type="File" @change="onChangeFile" />
const onChangeFile = (e) => {
  let file = e.target.files[0];
  const chunks = chunksFun(file);
  uploadFiles(chunks);
};
//切片
const chunksFun = (file, size = 1024 * 1024 * 1) => {
  const chunks = [];
  for (let i = 0; i < file.size; i += size) {
    chunks.push(file.slice(i, i + size));
  }
  return chunks;
};
//上传
const uploadFiles = (chunks) => {
  const list = [];
  for (let i = 0; i < chunks.length; i++) {
    const formData = new FormData();
    formData.append("index", i + "");
    formData.append("fileName", "test");
    formData.append("file", chunks[i]);
    list.push(
      fetch("http://localhost:888/upload", {
        method: "POST",
        body: formData,
      })
    );
  }
  Promise.all(list).then((res) => {
    fetch("http://localhost:888/merge", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        fileName: "xxx",
      }),
    });
  });
};

后端(服务端)

import multer from "multer";//处理上传(表单)
import express from "express";//服务
import cors from 'cors'//放行
import fs from 'node:fs'
import path from 'node:path'

const storage = multer.diskStorage({
    destination:function (req,file,cd){
        cd(null,'uploads/')//存储目录
    },
    filename (req,file,cd){
        cd(null,`${req.body.index}-${req.body.fileName}`)
    }
})

const upload =multer({storage})
const app = express()

app.use(cors())
app.use(express.json())

//接口
app.get('/',(req,res)=>{
    res.send('http://localhost:888')
})
app.post('/upload',upload.single('file'),(req,res)=>{
    res.send('ok')
})
app.post('/merge',(req,res)=>{
    const uploadDir = path.join(process.cwd(),'uploads')
    const dirs = fs.readdirSync(uploadDir)
    //排序
    dirs.sort((a,b)=>a.split('-')[0]-b.split('-')[0])
    const fileData = path.join(process.cwd(),'files',`${req.body.fileName}.zip`)
    dirs.forEach(item=>{
        fs.appendFileSync(fileData,fs.readFileSync(path.join(uploadDir,item)))
        fs.unlinkSync(path.join(uploadDir,item))
    })
    res.send('ok')
})

//启动服务
app.listen(888,()=>{
    console.log('http://localhost:888')
})