文件分片上传
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>