11 上传下载二

128 阅读1分钟

下载

router.get("/download2", (req, res) => {
  const fileName = encodeURIComponent("课程.png");
  res.set({
    "Content-Type": "application/octet-stream",
    "Content-Disposition": `attachment; filename=${fileName}`,
  });
  res.sendFile(path.resolve(__dirname, "imgs/avatar.png"));
  // res.download("./imgs/avatar.png");
});

以这种方式加fileName,需要注意axios的返回值,需要 res.headers.get("Content-disposition");

下载用sendFile或者download都可以,但自定义给文件命名download方法不行 前端接收时传{ responseType: 'blob'} 下载中就不用写 new Blob([res]) 传其他的比如 responseType: 'arraybuffer',就需要在前端写 new Blob,暂时不知道为什么 还有注意: responseType这个配置参数在get请求中可以不传参数,post不行

分片上传 前后端

前端

// 第一种切片
const fileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    // console.log("file", e.target.files![0]);
    const file = e.target.files![0];
    const chunks = chunkFun(file);
    uploadFile(chunks);
  };
  const chunkFun = (file, size = 1024 * 1024) => {
    const chunks = [];
    for (let i = 0; i < file.size; i += size) {
      chunks.push(file.slice(i, i + size));
    }
    return chunks;
  };
   const uploadFile = (chunks) => {
    const List = [];
    for (let i = 0; i < chunks.length; i++) {
      const formData = new FormData();
      formData.append("index", i);
      formData.append("total", chunks.length);
      formData.append("fileName", "xiezhen");
      formData.append("file", chunks[i]);
      List.push(sliceUpload(formData));
    }
    Promise.all(List).then((res) => {
      uploadMerge({ fileName: "myName" }).then((res) => {
        console.log("merge done", res);
      });
    });
  };
  
  // 第二种切片
   const fileChange2 = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files![0];
    const { name, size } = file;
    const chunkSlice = 1024 * 500;
    let start = 0;
    let index = 0;
    while (start < size) {
      let _blob;
      if (start + chunkSlice > size) {
        _blob = file.slice(start, size);
      } else {
        _blob = file.slice(start, start + chunkSlice);
      }
      const _file = new File([_blob], `${name}`);
      const _formData = new FormData();

      _formData.append("index", index + "");
      _formData.append("fileName", "chunkwenjianming");
      _formData.append("file", _file);

      await sliceUpload(_formData);
      start += chunkSlice;
      index++;
    }
    // 这是接口
    uploadMerge({ fileName: "视频" }).then((res) => {
      console.log("merge done", res);
    });
  };

后端

// 切片上传
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, "uploads/");
  },
  filename: (req, file, cb) => {
    cb(null, `${req.body.index}-${req.body.fileName}`);
  },
});
const upload = multer({ storage });
// 分片上传
router.post("/up", upload.single("file"), (req, res) => {
  res.send("ok");
});
//合并
router.post("/slice-merge", async (req, res) => {
  const uploadPath = "./uploads";
  let files = fs.readdirSync(path.join(process.cwd(), uploadPath));
  files = files.sort((a, b) => a.split("-")[0] - b.split("-")[0]);
  const writePath = path.join(
    process.cwd(),
    `video`,
    `${req.body.fileName}.mp4`
  );
  files.forEach((item) => {
    fs.appendFileSync(
      writePath,
      fs.readFileSync(path.join(process.cwd(), uploadPath, item))
    );
    fs.unlinkSync(path.join(process.cwd(), uploadPath, item));
  });

  res.send("ok 合并完了");
});