前端上传组件Plupload

Plupload 从入门到实战:核心用法与文件重命名全指南

Plupload 是一款功能强大、跨浏览器、高度可定制的前端文件上传组件,支持分片上传、拖拽上传、多文件上传、进度显示、文件类型/大小限制等核心功能,兼容 Flash、HTML5、Silverlight 等多种运行时,是企业级上传场景的首选方案。本文结合官方文档和实战需求,从基础用法、核心配置到文件重命名、常见场景,全面讲解 Plupload 的使用方法。


一、核心优势与适用场景

1. 核心优势

  • 跨浏览器/跨终端:兼容 IE6+、Chrome、Firefox、移动端浏览器
  • 多运行时支持:优先使用 HTML5,降级支持 Flash/Silverlight/HTML4
  • 分片上传:大文件自动分片,断点续传(需后端配合)
  • 高度可定制:UI 完全自定义,事件丰富,可灵活扩展
  • 功能全面:拖拽上传、多文件、类型/大小限制、进度条、文件过滤

2. 适用场景

  • 普通文件上传(图片/文档/视频)
  • 大文件分片上传(GB级文件)
  • 批量文件上传
  • 自定义上传 UI 交互
  • 需兼容低版本浏览器的上传场景

二、基础用法:快速上手

1. 安装/引入 Plupload

方式1:CDN 引入(快速测试)

1
2
3
4
<!-- 核心JS -->
<script src="https://cdn.jsdelivr.net/npm/plupload@3.1.5/dist/js/plupload.full.min.js"></script>
<!-- 可选:中文语言包 -->
<script src="https://cdn.jsdelivr.net/npm/plupload@3.1.5/dist/js/i18n/zh_CN.js"></script>

方式2:NPM 安装(工程化项目)

1
2
3
4
5
# 安装
npm install plupload --save

# 引入
import Plupload from 'plupload'

方式3:下载源码引入(本地部署)

Plupload GitHub 下载最新版本,解压后引入 dist/js/plupload.full.min.js

2. 基础 HTML 结构

1
2
3
4
5
6
7
<!-- 上传按钮容器 -->
<div id="uploader">
<button id="pickfiles">选择文件</button>
<button id="uploadfiles">开始上传</button>
<!-- 上传进度/结果显示 -->
<div id="filelist"></div>
</div>

3. 核心初始化配置(基础版)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// 初始化上传实例
var uploader = new plupload.Uploader({
// 必选配置
browse_button: 'pickfiles', // 选择文件按钮ID
url: '/api/upload', // 后端上传接口地址
// 可选配置
runtimes: 'html5,flash,silverlight,html4', // 运行时优先级,优先HTML5
max_file_size: '10mb', // 文件最大体积
filters: { // 文件过滤(类型/数量)
mime_types: [
{ title: "图片文件", extensions: "jpg,jpeg,png,gif" },
{ title: "文档文件", extensions: "pdf,doc,docx" }
],
max_file_count: 5 // 最多上传5个文件
},
flash_swf_url: '/plupload/js/Moxie.swf', // Flash运行时路径(需下载)
silverlight_xap_url: '/plupload/js/Moxie.xap', // Silverlight路径
chunk_size: '2mb', // 分片大小(大文件上传需配置)
rename: true, // 允许重命名(基础版)
unique_names: false, // 是否自动生成唯一文件名
// 自定义参数(传给后端)
multipart_params: {
token: 'user_token_123', // 身份验证
folder: 'upload/images' // 上传目录
},
// 语言配置
language: 'zh_CN',
init: {
// 初始化完成
PostInit: function() {
document.getElementById('filelist').innerHTML = '';
// 绑定上传按钮事件
document.getElementById('uploadfiles').onclick = function() {
uploader.start(); // 开始上传
return false;
};
},
// 选择文件后触发
FilesAdded: function(up, files) {
plupload.each(files, function(file) {
document.getElementById('filelist').innerHTML +=
`<div id="${file.id}">${file.name} (${plupload.formatSize(file.size)})
<b></b></div>`;
});
},
// 文件上传进度
UploadProgress: function(up, file) {
document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML =
`<span>${file.percent}%</span>`;
},
// 上传成功
FileUploaded: function(up, file, info) {
// info是后端返回的响应内容
console.log('文件上传成功:', file.name, info);
},
// 上传错误
Error: function(up, err) {
document.getElementById('filelist').innerHTML +=
`<div style="color: red;">错误:${err.code} - ${err.message}</div>`;
}
}
});

// 初始化上传器
uploader.init();

三、核心功能:文件重命名(重点)

文件重命名是 Plupload 高频需求,分为前端重命名(上传前修改文件名)和后端重命名,以下是两种主流实现方式:

方式1:上传前手动重命名(推荐)

通过 FilesAdded 事件修改文件对象的 name 属性,适用于自定义命名规则(如加时间戳、前缀、随机数)。

示例:添加时间戳前缀

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var uploader = new plupload.Uploader({
browse_button: 'pickfiles',
url: '/api/upload',
max_file_size: '10mb',
init: {
FilesAdded: function(up, files) {
plupload.each(files, function(file) {
// 1. 获取文件扩展名
var ext = plupload.parseExtension(file.name);
// 2. 生成新文件名(时间戳 + 随机数 + 扩展名)
var newName = `${Date.now()}_${Math.random().toString(36).substr(2, 8)}.${ext}`;
// 3. 重命名文件(核心:修改file.name)
file.name = newName;

// 显示重命名后的文件名
document.getElementById('filelist').innerHTML +=
`<div id="${file.id}">原文件名:${file.originalName} → 新文件名:${file.name}</div>`;
});
},
// 其他事件...
FileUploaded: function(up, file, info) {
console.log('上传的文件名:', file.name); // 输出重命名后的名称
}
}
});

uploader.init();

方式2:自动生成唯一文件名(简单版)

启用 unique_names 配置,Plupload 会自动生成唯一文件名(基于时间戳+随机数):

1
2
3
4
5
6
var uploader = new plupload.Uploader({
browse_button: 'pickfiles',
url: '/api/upload',
unique_names: true, // 开启自动唯一命名
// 其他配置...
});

方式3:自定义重命名规则(用户输入)

允许用户手动输入新文件名,适用于需要用户自定义名称的场景:

1
2
3
4
5
6
7
<!-- 新增输入框用于输入自定义名称 -->
<div id="uploader">
<button id="pickfiles">选择文件</button>
<input type="text" id="customName" placeholder="输入自定义文件名(不带扩展名)">
<button id="uploadfiles">开始上传</button>
<div id="filelist"></div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var uploader = new plupload.Uploader({
browse_button: 'pickfiles',
url: '/api/upload',
init: {
FilesAdded: function(up, files) {
plupload.each(files, function(file) {
// 保存原始文件名和扩展名
file.originalName = file.name;
file.ext = plupload.parseExtension(file.name);

// 绑定上传按钮点击事件时重命名
document.getElementById('uploadfiles').onclick = function() {
var customName = document.getElementById('customName').value.trim();
if (customName) {
// 使用用户输入的名称 + 原扩展名
file.name = `${customName}.${file.ext}`;
} else {
// 无输入则用时间戳命名
file.name = `${Date.now()}.${file.ext}`;
}
up.start();
return false;
};

document.getElementById('filelist').innerHTML +=
`<div id="${file.id}">${file.originalName}</div>`;
});
}
}
});

uploader.init();

四、进阶功能:分片上传(大文件)

Plupload 支持大文件分片上传,需前端配置分片大小,后端接收并合并分片:

1. 前端配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var uploader = new plupload.Uploader({
browse_button: 'pickfiles',
url: '/api/upload/chunk', // 分片上传接口
chunk_size: '5mb', // 每片5MB
chunk_count: 0, // 自动计算分片数
chunk_uploaded: function(up, file, info) {
// 单个分片上传成功回调
console.log(`分片 ${file.chunk_idx + 1}/${file.chunk_count} 上传成功`);
},
// 其他配置...
init: {
FileUploaded: function(up, file, info) {
// 所有分片上传完成后,通知后端合并
if (file.chunk_count === file.chunk_idx + 1) {
fetch('/api/upload/merge', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
filename: file.name,
chunkCount: file.chunk_count,
fileSize: file.size
})
}).then(res => res.json()).then(data => {
console.log('文件合并成功:', data);
});
}
}
}
});

2. 后端分片接收逻辑(伪代码)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Node.js 示例(Express)
app.post('/api/upload/chunk', (req, res) => {
const { chunk, chunk_idx, filename, chunk_count } = req.body;
// 1. 保存分片到临时目录
const chunkPath = `./temp/${filename}_${chunk_idx}`;
fs.writeFileSync(chunkPath, chunk);
// 2. 返回成功
res.json({ code: 0, msg: '分片上传成功' });
});

// 合并分片
app.post('/api/upload/merge', (req, res) => {
const { filename, chunkCount } = req.body;
// 1. 创建最终文件
const finalPath = `./uploads/${filename}`;
const writeStream = fs.createWriteStream(finalPath);
// 2. 按顺序合并分片
for (let i = 0; i < chunkCount; i++) {
const chunkPath = `./temp/${filename}_${i}`;
const chunkData = fs.readFileSync(chunkPath);
writeStream.write(chunkData);
// 3. 删除临时分片
fs.unlinkSync(chunkPath);
}
writeStream.end();
res.json({ code: 0, msg: '文件合并成功', path: finalPath });
});

五、常用事件与API

1. 核心事件(init 中配置)

事件名 触发时机 常用参数
PostInit 上传器初始化完成 up(上传实例)
FilesAdded 选择文件后 up, files(文件数组)
FilesRemoved 文件被移除后 up, files
UploadProgress 文件上传中(实时进度) up, file(当前文件)
FileUploaded 单个文件上传完成 up, file, info(后端响应)
UploadComplete 所有文件上传完成 up, files
Error 上传错误(文件过大/类型错误等) up, err(错误对象)
BeforeUpload 文件上传前 up, file

2. 核心API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 初始化
uploader.init();

// 选择文件后开始上传
uploader.start();

// 暂停上传
uploader.stop();

// 移除指定文件
uploader.removeFile(file);

// 清空所有文件
uploader.splice();

// 获取所有文件
var files = uploader.files;

// 销毁上传器
uploader.destroy();

六、常见问题与解决方案

1. 文件名中文乱码

1
2
3
4
5
6
7
// 前端处理:编码文件名
multipart_params: {
filename: encodeURIComponent(file.name)
}

// 后端处理:解码
const filename = decodeURIComponent(req.body.filename);

2. 低版本IE兼容

  • 确保引入 Flash/Silverlight 运行时文件
  • 配置 runtimes: 'flash,html4' 优先使用 Flash
  • 测试 IE6-9 的兼容性

3. 上传进度不显示

  • 检查 UploadProgress 事件是否正确绑定
  • 确保后端返回正确的 Content-Length
  • 分片上传时,进度是单个分片的进度,需手动计算总进度

4. 文件重命名不生效

  • 必须在 FilesAddedBeforeUpload 事件中修改 file.name
  • 避免在 FileUploaded 中修改(已上传完成)
  • 检查是否开启 unique_names 覆盖了自定义名称

七、实战优化建议

  1. UI 自定义:隐藏 Plupload 原生样式,自定义上传按钮、进度条、文件列表
  2. 错误处理:完善各种错误场景(文件过大、类型错误、网络中断、后端异常)
  3. 断点续传:记录已上传的分片,重新上传时跳过已上传的分片
  4. 并发控制:配置 max_concurrent_uploads: 3 限制同时上传的文件数
  5. 进度优化:大文件分片上传时,计算总进度(已上传分片数/总分片数)
  6. 清理临时文件:后端定期清理未合并的分片文件

总结

关键点回顾

  1. 基础使用:核心配置 browse_buttonurl,通过 init 绑定事件处理上传流程。
  2. 文件重命名:核心是修改文件对象的 name 属性,推荐在 FilesAdded 事件中实现,支持自定义规则(时间戳、用户输入等)。
  3. 进阶功能:分片上传需配置 chunk_size,后端需接收分片并合并;事件系统是扩展功能的核心。

Plupload 虽然是老牌组件,但功能稳定、兼容性强,通过灵活配置和事件扩展,可满足绝大多数企业级上传需求,文件重命名作为高频需求,核心是掌握 file.name 的修改时机和规则设计。


前端上传组件Plupload
https://cszy.top/2017-08-07 前端上传组件plupload/
作者
csorz
发布于
2017年8月7日
许可协议