Skip to content

Instantly share code, notes, and snippets.

@semlinker
Created May 11, 2021 14:10
Show Gist options
  • Save semlinker/af57349c16d203cc2ec845d4b5a6b445 to your computer and use it in GitHub Desktop.
Save semlinker/af57349c16d203cc2ec845d4b5a6b445 to your computer and use it in GitHub Desktop.
目录上传和压缩目录上传示例
const path = require("path");
const Koa = require("koa");
const cors = require("@koa/cors");
const multer = require("@koa/multer");
const Router = require("@koa/router");
const fse = require("fs-extra");
const app = new Koa();
const router = new Router();
const paths = path.sep + ["public", "upload"].join(path.sep);
const UPLOAD_DIR = path.join(__dirname, paths);
const storage = multer.diskStorage({
destination: async function (req, file, cb) {
let relativePath = file.originalname.replace(/@/g, path.sep);
let index = relativePath.lastIndexOf(path.sep);
let fileDir = path.join(UPLOAD_DIR, relativePath.substr(0, index));
await fse.ensureDir(fileDir);
cb(null, fileDir);
},
filename: function (req, file, cb) {
let parts = file.originalname.split("@");
cb(null, `${parts[parts.length - 1]}`);
},
});
const multerUpload = multer({ storage });
router.get("/", async (ctx) => {
ctx.body = "文件目录上传示例(阿宝哥)";
});
router.post(
"/upload/multiple",
multerUpload.fields([
{
name: "file",
},
]),
async (ctx, next) => {
ctx.body = {
status: "success",
msg: "文件上传成功",
};
}
);
// 注册中间件
app.use(cors());
app.use(router.routes()).use(router.allowedMethods());
app.listen(3000, () => {
console.log("app starting at port 3000");
});
const path = require("path");
const Koa = require("koa");
const cors = require("@koa/cors");
const multer = require("@koa/multer");
const Router = require("@koa/router");
const app = new Koa();
const router = new Router();
const UPLOAD_DIR = path.join(__dirname, "/public/upload");
const storage = multer.diskStorage({
destination: async function (req, file, cb) { // 设置文件的存储目录
cb(null, UPLOAD_DIR);
},
filename: function (req, file, cb) { // 设置文件名
cb(null, `${file.originalname}`);
},
});
const multerUpload = multer({ storage });
router.get("/", async (ctx) => {
ctx.body = "压缩文件目录上传示例(阿宝哥)";
});
router.post(
"/upload/multiple",
multerUpload.fields([
{
name: "file",
},
]),
async (ctx, next) => {
ctx.body = {
status: "success",
msg: "文件上传成功",
};
}
);
// 注册中间件
app.use(cors());
app.use(router.routes()).use(router.allowedMethods());
app.listen(3000, () => {
console.log("app starting at port 3000");
});
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>文件目录上传示例</title>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jszip/3.5.0/jszip.min.js"></script>
</head>
<body>
<input type="file" id="uploadFile" webkitdirectory />
<button id="submit" onclick="uploadFile()">上传文件</button>
<script>
const uploadFileEle = document.querySelector("#uploadFile");
const uploadOptions = { needZip: false };
const request = axios.create({
baseURL: "http://localhost:3000/",
timeout: 5000,
});
async function uploadFile({ needZip } = uploadOptions) {
if (!uploadFileEle.files.length) return;
let fileList = uploadFileEle.files;
if (needZip) {
let webkitRelativePath = fileList[0].webkitRelativePath;
let zipFileName = webkitRelativePath.split("/")[0] + ".zip";
fileList = [await generateZipFile(zipFileName, fileList)];
}
uploadFiles({
url: "/upload/multiple",
files: fileList,
});
}
function generateZipFile(
zipName,
files,
options = { type: "blob", compression: "DEFLATE" }
) {
return new Promise((resolve, reject) => {
const zip = new JSZip();
for (let i = 0; i < files.length; i++) {
zip.file(files[i].webkitRelativePath, files[i]);
}
zip.generateAsync(options).then(function (blob) {
zipName = zipName || Date.now() + ".zip";
const zipFile = new File([blob], zipName, {
type: "application/zip",
});
resolve(zipFile);
});
});
}
function uploadFiles({ url, files, fieldName = "file" }) {
if (!url || !files.length) return;
let formData = new FormData();
for (let i = 0; i < files.length; i++) {
// 压缩目录后上传直接使用文件名即可,目录上传再使用webkitRelativePath属性
// formData.append(fieldName, files[i], files[i].name);
// 对webkitRelativePath路径进行处理,确保@koa/multer能正确接收路径
formData.append(fieldName, files[i], files[i].webkitRelativePath.replace(/\//g, "@"));
}
return request.post(url, formData);
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment