
Security News
Axios Maintainer Confirms Social Engineering Attack Behind npm Compromise
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.
mpa-uploader
Advanced tools
该组件负责将文件上传到云空间。整个上传文件过程,由以下 6 个阶段组成:
名词解释:
上传组件提供了以下 API:
// 添加一个上传文件任务
addFiles(items, pid, behavior) { }
// 添加一个上传文件夹任务
addFolder(item, pid, behavior) { }
// 移除任务
remove(tid) { }
// 恢复任务
resume(tid) { }
// 暂停任务
async pause(tid) { }
// 销毁当前组件
destroy() { }
同时,组件在工作过程,会触发一些事件,调用方可以根据自己的需求订阅
// 新的任务,当调用 addFiles/addFolder 方法时触发
fileUploder.on("new-tasks", (tasks) => {});
// 移除任务,当调用 remove 方法时触发
fileUploder.on("remove-task", (tid) => { });
// 任务的状态发生变更,status 取值:ERROR: -1, WAITING: 0, UPLOADING: 1, AUSE: 2, COMPLETE: 3,
fileUploder.on("task-status-change", (tid, status) => { });
// 上传文件的状态发生变更 status 取值:ERROR: -1, WAITING: 0, UPLOADING: 1, AUSE: 2, COMPLETE: 3,
fileUploder.on("file-status-change", (tid, fid, status) => { });
// 上传速度,其中 e :{tid:'任务ID', rate:'上传速度(单位bytes)', commit:'当前已上传多少(单位bytes)'},
fileUploder.on("upload-speed", (e) => {});
// 上传进度,其中 e :{tid:'任务ID', uploaded:'已上传字节数', total:'任务总大小'}
fileUploder.on("upload-progress", (e) => { });
// 开始计算文件MD5
fileUploder.on("begin-hash", (tid, fid) => { });
// 计算文件MD5结束
fileUploder.on("end-hash", (tid, fid) => { });
// 计算文件MD5进度:e = { tid: '', fid: '', fileName: '文件名', percent: 进度值[0-100] }
fileUploder.on("hash-progress", (e) => { });
// 准备初始化文件
fileUploder.on("begin-prepare", (tid, fid) => { })
// 初始化文件结束
fileUploder.on("end-prepare", (tid, fid) => { });
// 初始化文件结果 file = {metadatas: '文件元数据', md5: '文件hash值', uploadId: '上传ID', blockInfo: '分块信息'}
fileUploder.on("prepared", (file) => { });
// 准备提交分块信息
fileUploder.on("begin-commit-blocks", (tid, fid) => {});
// 提交分块信息结束
fileUploder.on("end-commit-blocks", (tid, fid) => {});
// 准备上传文件
fileUploder.on("begin-upload-file", (tid, fid) => {})
// 上传文件结束
fileUploder.on("end-upload-file", (tid, fid) => {});
// 开始合并文件
fileUploder.on("begin-merge-file", (tid, fid) => {});
// 合并文件结束
fileUploder.on("end-merge-file", (tid, fid) => {});
// 上传被取消,一般调用 pause 方法时,会触发该事件
fileUploder.on("abort", (tid) => {});
// 上传完成
fileUploder.on("complete", (task) => {});
// 上传出错 e = {tid, fid, code, message}
// code 取值:
// OK: 0,
// USER_ABORT: 1,
// CALC_MD5_FAILED: 2,
// PREPARE_UPLOAD_FAILED: 3,
// COMMIT_BLOCKS_FAILED: 4,
// UPLOAD_FILE_FAILED: 5,
// MERGE_FILE_FAILED: 6,
// UNKNOWN: 7,
fileUploder.on("error", (e) => { });
使用组件之前,需要现对其实例化操作,实例化需要一些必须的参数,需要提供。
import FileUploader from "./FileUploader";
// 参数
const options = {
domain: "http://xxxx.com", // 接口域名
debug: true, // 是否调试模式, 将打印大量信息
headers?: {
deviceType: "1",
spaceId: "0583d",
userId: "",
token: "",
deviceId: "",
}, // 请求头信息,如果存在 cookies,则可以不用传递
};
// 实例化
const fileUploder = new FileUploader(options);
你可以上传文件或者文件夹,添加完成后,系统将通过事件的方式,告知添加的结果,主要包含 2 个 API:
示例
<template>
<input type="file" @change="handleFileUpload" multiple />
<input type="file" @change="handleFolderUpload" webkitdirectory />
</template>
const behavior = "RENAME" // 文件重命名行为
const pid = "1111" // 要上传文件的上级文件夹 ID
const fileUploder = new FileUploader(options);
// 上传文件
handleFileUpload(event) {
const target = event.target;
const files = Array.from(target.files); // 文件列表
const ok = fileUploader.addFiles(files, pid, behavior);
if (!ok) return;// 文件添加失败
}
// 上传文件夹
handleFolderUpload(event) {
const target = event.target;
const files = Array.from(target.files);
const ok = fileUploader.addFolder(files, pid, behavior);
if (!ok) return; // 文件夹添加失败
}
// 添加文件后,创建了一个新任务的回调
fileUploder.on("new-tasks", tasks => {
// 任务列表
// 任务对象属性组成
// {
// tid: '', // 任务ID
// pid: '', // 上传文件的上级文件夹 ID
// isdir: false, // 是否是文件夹
// name: 'file.name', // 任务名称
// size: 1000, // 要上传文件(夹)的总大小 单位 byte
// behavior: 'RENAME', // 文件重名行为
// status: 0, // FileStatus 任务状态,见下列表
// }
// const FileStatus = {
// ERROR: -1, // 错误
// WAITING: 0, // 等待上传
// UPLOADING: 1, // 上传中
// PAUSE: 2, // 暂停中
// COMPLETE: 3, // 上传完成
// };
})
通过调用 pause,可以取消任务,一旦被取消,将触发 abort 和 task-status-change 事件,调用方可以根据自身逻辑处理渲染层。
pause(tid): 暂停任务
const fileUploder = new FileUploader(options);
fileUploder.on("abort", (tid) => {
// 任务已暂停
});
fileUploder.on("task-status-change", (tid, status) => {
// 更新页面上的任务状态
});
const tid = "929w222";
fileUploder.pause(tid);
通过调用 resume() 可以继续上传被暂停或者出错的任务,一旦任务开始,将触发 task-status-change 事件
const fileUploder = new FileUploader(options);
fileUploder.on("task-status-change", (tid, status) => {
// 更新页面上的任务状态
});
const tid = "929w222";
fileUploder.resume(tid);
你可以通过 tid ,即 TaskId 删除任务,删除完成后,将通过事件的方式,通知你已删除完成。
remove(tid) : 删除任务
const fileUploder = new FileUploader(options);
fileUploder.on("remove-task", (tid) => {
// 任务已删除
});
const tid = "929w222";
fileUploder.remove(tid);
上传文件分 5 个步骤,将依次触发下面的事件(注意,不是每个事件一定都会触发)
示例
const fileUploader = new FileUploader(options);
fileUploader.on("begin-hash" (tid, fid) => {
// 开始计算文件MD5
// tid, TaskId, 即任务 ID,随机生成的标识
// fid, FileId, 文件ID,随机生成的标识
})
fileUploader.on("end-hash" (tid, fid) => {
// 计算文件MD5完成
})
fileUploader.on("hash-progress" ({ tid, fid, fileName, percent }) => {
// 正在计算文件MD5
// fileName 正在计算的文件名
// percent 当前进度 1-100
})
fileUploader.on("complete", (task) => {
// 文件上传完成
})
View
<div class="hello">
<span>文件夹</span>
<input type="file" @change="handleFolderUpload" webkitdirectory multiple />
<br />
<span>文件</span>
<input type="file" @change="handleFileUpload" multiple />
<br />
<table border="1">
<tr v-for="task of tasks" :key="task.tid">
<td>任务ID: {{ task.tid }}</td>
<td>状态:{{ task.status }}</td>
<td>速度:{{ speeder(task.tid) }}</td>
<td>进度:{{ processer(task.tid) }}</td>
<td>
<button @click="onStartTask(task.tid)">开始</button>
<button @click="onCancelTask(task.tid)">暂停</button>
<button @click="onRemoveTask(task.tid)">删除</button>
</td>
</tr>
</table>
</div>
Javascript:
import FileUploader from "mpa-upload-components";
import { bytesToSize } from "mpa-upload-components/src/utils";
const options = {
debug: true,
domain: "http://xxx.com",
headers: {
deviceType: "",
spaceId: "",
userId: "",
token: "",
deviceId: "",
},
};
const pid = "上级目录的ID";
export default {
name: "HelloWorld",
props: {
msg: String,
},
data() {
return {
fileMd5: null,
percent: 0,
tasks: [],
speeds: [],
progresses: [],
fileUploader: null,
};
},
methods: {
async handleFolderUpload(event) {
const target = event.target;
const files = Array.from(target.files);
const task = this.fileUploader.addFolder(files, pid);
},
async handleFileUpload(event) {
const target = event.target;
const files = Array.from(target.files);
const task = this.fileUploader.addFiles(files, pid);
},
onStartTask(tid) {
this.fileUploader.resume(tid);
},
onCancelTask(tid) {
this.fileUploader.pause(tid);
},
onRemoveTask(tid) {
this.fileUploader.remove(tid);
},
},
computed: {
speeder() {
return (tid) => {
const speed = this.speeds.find((t) => t.tid === tid);
if (!speed) return "";
return `${speed.rate}kb/s`;
};
},
processer() {
return (tid) => {
const progress = this.progresses.find((t) => t.tid === tid);
if (!progress) return "";
const value = ~~((progress.uploaded / progress.total) * 100);
return `${progress.uploaded}/${progress.total} (${value})%`;
};
},
},
created() {
this.fileUploader = new FileUploader(options);
this.fileUploader.on("new-tasks", (tasks) => {
this.tasks.push(...tasks);
});
this.fileUploader.on("remove-task", (tid) => {
const index = this.tasks.findIndex((task) => task.tid === tid);
this.tasks.splice(index, 1);
});
this.fileUploader.on("task-status-change", (tid, status) => {
const task = this.tasks.find((task) => task.tid === tid);
task.status = status;
});
this.fileUploader.on("upload-speed", (e) => {
const speed = this.speeds.find((t) => t.tid === e.tid);
if (speed) {
speed.rate = bytesToSize(e.rate);
speed.commit = e.commit;
} else {
this.speeds.push(e);
}
});
this.fileUploader.on("upload-progress", (e) => {
const progress = this.progresses.find((t) => t.tid === e.tid);
if (progress) {
progress.total = e.total;
progress.uploaded = e.uploaded;
} else {
this.progresses.push(e);
}
});
},
};
FAQs
## 简介
The npm package mpa-uploader receives a total of 0 weekly downloads. As such, mpa-uploader popularity was classified as not popular.
We found that mpa-uploader demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.