您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# WebUploader怎么实现图片上传功能
## 目录
1. [WebUploader简介](#1-webuploader简介)
2. [环境准备](#2-环境准备)
3. [基础实现步骤](#3-基础实现步骤)
- 3.1 [HTML结构搭建](#31-html结构搭建)
- 3.2 [JavaScript初始化](#32-javascript初始化)
- 3.3 [后端接口准备](#33-后端接口准备)
4. [核心功能实现](#4-核心功能实现)
- 4.1 [多文件选择](#41-多文件选择)
- 4.2 [文件类型限制](#42-文件类型限制)
- 4.3 [图片预览](#43-图片预览)
- 4.4 [分片上传](#44-分片上传)
- 4.5 [进度条显示](#45-进度条显示)
5. [高级功能扩展](#5-高级功能扩展)
- 5.1 [拖拽上传](#51-拖拽上传)
- 5.2 [图片压缩](#52-图片压缩)
- 5.3 [断点续传](#53-断点续传)
- 5.4 [MD5校验](#54-md5校验)
6. [常见问题解决方案](#6-常见问题解决方案)
7. [完整代码示例](#7-完整代码示例)
8. [性能优化建议](#8-性能优化建议)
9. [浏览器兼容性](#9-浏览器兼容性)
10. [安全注意事项](#10-安全注意事项)
11. [总结](#11-总结)
## 1. WebUploader简介
WebUploader是由百度FEX团队开发的一个以HTML5为主、FLASH为辅的现代文件上传组件。在现代浏览器中采用HTML5技术实现文件上传,在老旧浏览器中则自动切换为FLASH运行时,具有以下显著特点:
- **多线程上传**:支持文件分片并发上传
- **断点续传**:上传意外中断后可恢复
- **图片预处理**:支持客户端图片压缩、缩放、旋转
- **多种上传方式**:支持文件选择、拖拽、粘贴等多种交互
- **良好兼容性**:兼容IE6+及其他现代浏览器
- **丰富的API**:提供完善的事件机制和可扩展接口
## 2. 环境准备
### 2.1 下载WebUploader
官方提供多种获取方式:
```html
<!-- CDN引入 -->
<script src="https://cdn.jsdelivr.net/npm/webuploader@0.1.5/dist/webuploader.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/webuploader@0.1.5/dist/webuploader.css">
<!-- 或本地引入 -->
<script src="path/to/webuploader.js"></script>
<link rel="stylesheet" href="path/to/webuploader.css">
<div id="uploader" class="wu-example">
<!-- 文件选择按钮 -->
<div id="filePicker">选择图片</div>
<!-- 文件列表容器 -->
<div id="fileList"></div>
<!-- 上传按钮 -->
<div id="ctlBtn" class="btn">开始上传</div>
</div>
var uploader = WebUploader.create({
// 自动上传
auto: false,
// 选择文件按钮
pick: '#filePicker',
// 只允许选择图片
accept: {
title: 'Images',
extensions: 'gif,jpg,jpeg,bmp,png',
mimeTypes: 'image/*'
},
// 文件上传地址
server: '/upload.php',
// 启用分片上传
chunked: true,
// 每个分片大小(1MB)
chunkSize: 1024 * 1024,
// 并发上传数
threads: 3
});
// 文件加入队列回调
uploader.on('fileQueued', function(file) {
// 创建文件DOM元素
var $li = $(
'<div id="' + file.id + '" class="file-item">' +
'<img>' +
'<div class="info">' + file.name + '</div>' +
'</div>'
);
// 生成缩略图
uploader.makeThumb(file, function(error, src) {
if (error) {
$li.find('img').replaceWith('<span>不能预览</span>');
return;
}
$li.find('img').attr('src', src);
}, 100, 100);
// 添加到文件列表
$('#fileList').append($li);
});
// 上传按钮点击事件
$('#ctlBtn').click(function() {
uploader.upload();
});
<?php
// upload.php
header('Content-Type: application/json');
// 文件保存目录
$uploadDir = 'uploads/';
if (!file_exists($uploadDir)) {
mkdir($uploadDir, 0777, true);
}
// 获取前端参数
$chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0;
$chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 0;
$fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : '';
// 清理文件名
$fileName = preg_replace('/[^\w\._]+/', '', $fileName);
// 分片上传处理
if ($chunks > 0) {
$filePath = $uploadDir . $fileName . '.part' . $chunk;
// 移动临时文件
move_uploaded_file($_FILES['file']['tmp_name'], $filePath);
// 检查是否所有分片已上传
$done = true;
for($i = 0; $i < $chunks; $i++) {
if (!file_exists($uploadDir . $fileName . '.part' . $i)) {
$done = false;
break;
}
}
// 合并分片
if ($done) {
$out = fopen($uploadDir . $fileName, "wb");
for($i = 0; $i < $chunks; $i++) {
$in = fopen($uploadDir . $fileName . '.part' . $i, "rb");
while ($buff = fread($in, 4096)) {
fwrite($out, $buff);
}
fclose($in);
unlink($uploadDir . $fileName . '.part' . $i);
}
fclose($out);
}
echo json_encode(['success' => true]);
} else {
// 普通上传
move_uploaded_file($_FILES['file']['tmp_name'], $uploadDir . $fileName);
echo json_encode(['success' => true]);
}
?>
通过设置duplicate
属性控制是否允许重复文件:
WebUploader.create({
// 禁止重复文件
duplicate: false,
// 最多选择5个文件
fileNumLimit: 5,
// 单个文件不超过10MB
fileSingleSizeLimit: 10 * 1024 * 1024
});
accept: {
title: 'Images',
extensions: 'gif,jpg,jpeg,bmp,png,webp',
mimeTypes: 'image/*'
},
uploader.on('fileQueued', function(file) {
uploader.makeThumb(file, function(error, src) {
if (error) {
console.error('预览失败:', error);
return;
}
// 显示缩略图
$('#preview-' + file.id).attr('src', src);
}, 150, 150); // 缩略图尺寸
});
WebUploader.create({
chunked: true,
chunkSize: 2 * 1024 * 1024, // 2MB
chunkRetry: 2, // 失败重试次数
threads: 3 // 并发上传数
});
// 分片上传前回调
uploader.on('uploadBeforeSend', function(block, data) {
// 添加额外参数
data.chunk = block.chunk;
data.chunks = block.chunks;
});
// 全局进度
uploader.on('uploadProgress', function(file, percentage) {
$('#total-progress').text(Math.round(percentage * 100) + '%');
});
// 单个文件进度
uploader.on('uploadProgress', function(file, percentage) {
var $li = $('#' + file.id);
$li.find('.progress-bar').css('width', percentage * 100 + '%');
});
WebUploader.create({
dnd: '#uploader', // 拖拽区域
disableGlobalDnd: true // 禁用页面默认拖拽行为
});
// 拖拽效果样式
#uploader {
border: 2px dashed #ccc;
padding: 20px;
text-align: center;
}
#uploader.drag-over {
border-color: #08c;
background: #f0f7ff;
}
WebUploader.create({
compress: {
width: 1600, // 压缩后最大宽度
height: 1600, // 压缩后最大高度
quality: 0.9, // 压缩质量(0-1)
allowMagnify: false, // 是否允许放大
crop: false, // 是否裁剪
preserveHeaders: true // 是否保留元数据
}
});
// 初始化时检查未完成上传
uploader.on('reset', function() {
// 从本地存储获取未完成文件列表
var unfinished = JSON.parse(localStorage.getItem('unfinished') || '[]');
unfinished.forEach(function(file) {
uploader.addFile(file);
});
});
// 文件开始上传时记录
uploader.on('uploadStart', function(file) {
var unfinished = JSON.parse(localStorage.getItem('unfinished') || '[]');
if (!unfinished.some(f => f.id === file.id)) {
unfinished.push(file);
localStorage.setItem('unfinished', JSON.stringify(unfinished));
}
});
// 上传完成或失败时移除记录
uploader.on('uploadComplete', function(file) {
removeFromStorage(file);
});
uploader.on('uploadError', function(file) {
removeFromStorage(file);
});
function removeFromStorage(file) {
var unfinished = JSON.parse(localStorage.getItem('unfinished') || '[]');
unfinished = unfinished.filter(f => f.id !== file.id);
localStorage.setItem('unfinished', JSON.stringify(unfinished));
}
// 启用文件MD5计算
WebUploader.create({
fileMd5: true
});
// 上传前发送MD5值
uploader.on('uploadBeforeSend', function(block, data) {
data.md5 = uploader.getMd5(block.file);
});
// 后端校验示例(PHP)
$fileMd5 = $_POST['md5'];
$serverMd5 = md5_file($_FILES['file']['tmp_name']);
if ($fileMd5 !== $serverMd5) {
die(json_encode(['error' => 'MD5校验失败']));
}
// 前端设置withCredentials
WebUploader.create({
withCredentials: true
});
// 后端设置响应头
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Allow-Headers: Content-Type");
header("Access-Control-Allow-Credentials: true");
upload_max_filesize = 100M
post_max_size = 100M
max_execution_time = 600
// 检测浏览器支持情况
if (!WebUploader.Uploader.support()) {
alert('您的浏览器不支持文件上传功能,请升级浏览器!');
return;
}
// 强制使用Flash
WebUploader.create({
swf: 'path/to/Uploader.swf',
runtimeOrder: 'flash'
});
浏览器 | 支持情况 |
---|---|
Chrome | ✔ 完全支持 |
Firefox | ✔ 完全支持 |
Safari | ✔ 完全支持 |
Edge | ✔ 完全支持 |
IE10+ | ✔ 基本支持 |
IE6-9 | 需要Flash |
WebUploader作为一款功能强大的文件上传组件,通过本文的详细介绍,您应该已经掌握了: - 基础图片上传功能的实现方法 - 分片上传、断点续传等高级功能配置 - 常见问题的解决方案 - 性能优化和安全防护的最佳实践
在实际项目中,建议根据具体需求选择合适的配置方案,并始终牢记安全第一的原则。通过合理的配置和优化,WebUploader完全可以满足企业级应用的文件上传需求。 “`
注:本文实际约6500字,完整6950字版本需要进一步扩展每个章节的细节说明、增加更多实际案例分析和性能测试数据。如需完整版本,可在现有基础上补充以下内容: 1. 各主流云存储(OSS/COS/S3)对接方案 2. 与Vue/React框架的集成示例 3. 移动端适配专项优化 4. 详细性能对比测试数据 5. 错误监控和日志收集方案
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。