文件分片上传

npm install express multiparty body-parser fs-extra

mkdir public temp

touch server.js public/index.html

server.js;

const express = require("express");
const bodyParser = require("body-parser");
const multiparty = require("multiparty");
const fse = require("fs-extra");
const path = require("path");
const app = express();
const fs = require("fs");

app.use(express.static(__dirname + "/public"));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
const UPLOAD_DIR = path.resolve(__dirname, "public/upload");

app.post("/upload", async function (req, res) {
  const form = new multiparty.Form({ uploadDir: "temp" });
  form.parse(req);

  form.on("file", async (name, chunk) => {
    //存放切片的目录
    let chunkDir = `${UPLOAD_DIR}/${chunk.originalFilename.split(".")[0]}`;
    if (!fse.existsSync(chunkDir)) {
      await fse.mkdirs(chunkDir);
    }
    //原来文件。index.ext
    var dPath = path.join(chunkDir, chunk.originalFilename.split(".")[1]);
    await fse.move(chunk.path, dPath, { overwrite: true });
  });
  res.send("文件上传成功");
});

app.post("/merge", async function (req, res) {
  let name = req.body.name;
  let fname = name.split(".")[0];
  let chunkDir = path.join(UPLOAD_DIR, fname);
  let chunks = await fse.readdir(chunkDir);
  await chunks
    .sort((a, b) => a - b)
    .map(async (chunkPath) => {
      await fse.appendFileSync(
        path.join(UPLOAD_DIR, name),
        fs.readFileSync(`${chunkDir}/${chunkPath}`)
      );
      await fse.removeSync(chunkDir);
    });
  await res.send({
    msg: "合并成功",
    url: `http://localhost:3000/upload/${name}`,
  });
});
app.listen(3000);
console.log("listen 3000");

node server.js

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <!-- <script src="axios.min.js"></script> -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  </head>

  <body>
    <input type="file" id="btnFile" />
    <input type="button" name="" onclick="upload(0)" value="上传" />
  </body>
  <script>
    let btnFile = document.querySelector("#btnFile");
    let chunkSize = 1024 * 1024;
    function upload(index) {
      let file = btnFile.files[0];
      let [fname, fext] = file.name.split(".");
      let start = index * chunkSize;
      if (start > file.size) {
        setTimeout(() => {
          merge(file.name);
        }, 5000);
        return;
      }
      let blob = file.slice(start, start + chunkSize);
      let blobName = `${fname}.${index}.${fext}`;
      let blobFile = new File([blob], blobName);

      let formData = new FormData();
      formData.append("file", blobFile);

      axios.post("/upload", formData).then((res) => {
        console.log(res);
        upload(++index);
      });
    }

    function merge(name) {
      axios.post("/merge", { name: name }).then((res) => {
        console.log("object", res);
      });
    }
  </script>
</html>

office

Last Updated:
Contributors: 刘荣杰