Skip to content

Commit 2ffc939

Browse files
committed
readme.md
1 parent d69fbf8 commit 2ffc939

12 files changed

+5872
-2779
lines changed

README.md

+275
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
# js-web-uploader
2+
基于html5的文件上传工具
3+
4+
5+
6+
## 安装
7+
8+
```sh
9+
npm install js-web-uploader --save
10+
```
11+
12+
## 注意
13+
14+
* 该上传工具仅包含JavaScript部分
15+
* 支持文件分块上传、断点续传,秒传
16+
* 内部http请求使用XHR(XMLHttpRequest)对象,文件分块基于Blob.prototype.slice
17+
18+
19+
20+
## 使用说明
21+
使用时需创建一个Uploader实例,假设实例为uploader:
22+
* 批量上传:uploader.upload()
23+
* 单个文件上传 uploader.queue[0].upload()
24+
* 批量暂停:uploader.abort()
25+
* 单个文件上传 uploader.queue[0].abort()
26+
* 文件状态 uploader.queue[0].status (详见附录2)
27+
28+
### 普通上传
29+
30+
```js
31+
import { Uploader } from 'js-web-uploader';
32+
const uploader = new Uploader({
33+
inputElem: 'uploadInput', // 选择文件的元素
34+
uploadUrl: '',// 文件上传路径
35+
})
36+
```
37+
38+
### 分块上传
39+
##### 分块上传需计算文件hash值,并将其作为文件的唯一标识,可参考以下思路:
40+
* 客户端上传文件分块,同时携带所属文件hash值、文件分块数量、分块索引(第几个分块)
41+
* 服务器接收文件分块并保存分块信息,文件以hash值作为唯一标识
42+
* 服务器在每个分块上传后检测是否该文件所有分块已经上传,若已上传所有分块,则将分块合并成文件保存,并将获取文件的url返回给客户端
43+
44+
```js
45+
import { Uploader } from 'js-web-uploader';
46+
const uploader = new Uploader({
47+
inputElem: 'uploadInput', // 选择文件的元素
48+
uploadUrl: '',// 文件上传路径
49+
// 填写chunkSize参数触发分块上传
50+
chunkSize: 1 * 1024 * 1024, // 分块大小,单位byte,可以为数值或function,function参数qf为队列文件(详见附录1)
51+
// chunkSize: qf=>1 * 1024 * 1024,
52+
uploadType: 0, // (分块)上传方式 0-并行上传 1-串行上传 默认值:0
53+
data:{}, // 上传时携带的数据,值可以是对象或funtion(详见附录1)
54+
})
55+
```
56+
57+
### 断点续传
58+
59+
断点续传基于分块上传,即服务器保存文件已上传分块信息,在上传前获取文件上传状态,将未上传的文件分块继续上传
60+
(继续上传时调用upload方法)
61+
62+
```js
63+
import { Uploader } from 'js-web-uploader';
64+
const uploader = new Uploader({
65+
// ... 省略其他参数
66+
/** 检测文件上传状态方法 */
67+
checkMethod: (qf, resolve) => {
68+
// 请求文件上传状态
69+
// 调用 resolve 方法告知已上传分块,传参为数组 例:resolve([0,1,2])
70+
}
71+
})
72+
73+
```
74+
75+
### 秒传
76+
在checkMethod里向服务器获取文件上传状态
77+
* 若文件已完成上传,则服务器直接返回文件访问url,客户端在checkMethod里resolve所有分块
78+
* 若未完成上传,则在checkMethod里resolve已上传分块
79+
80+
```js
81+
import { Uploader } from 'js-web-uploader';
82+
const uploader = new Uploader({
83+
// ... 省略其他参数
84+
secondUpload:true,
85+
checkMethod: (qf, resolve) => {
86+
// ... 请求文件上传状态
87+
// 已完成上传
88+
// 调用 resolve 方法告知已上传分块,若分块数量为3,则:resolve([0,1,2])
89+
resolve([0,1,2])
90+
}
91+
})
92+
93+
```
94+
### API
95+
* upload() 上传文件
96+
* setOptions(options) 设置参数
97+
* remove(index) 删除指定下标的文件(queue中的qf)
98+
* on(event,callback) 注册监听事件,详见附录
99+
* trigger(event,...args) 触发指定事件,arg为传入的参数
100+
101+
```js
102+
// 文件选择时
103+
uploader.on('select', files => {
104+
// files-选择的文件列表
105+
})
106+
// 移除文件前
107+
uploader.on('beforeRemove', qfs => {
108+
// qfs- qf列表
109+
// 若返回值为 false, 0, '', null中的任一值,则将不执行移除操作
110+
// 若返回值为Promise实例且resolve false, 0, '', null中的任一值,则将不执行移除操作
111+
})
112+
// 移除文件后
113+
uploader.on('remove', qfs => {
114+
// qfs- qf列表
115+
})
116+
// 超出数量时
117+
uploader.on('countExceed', (totalCount, maxCount) => {
118+
// totalCount 总数量
119+
// maxCount 最大数量
120+
})
121+
// 单个文件超出大小限制时
122+
uploader.on('sizeExceed', (eFiles, maxSize) => {
123+
// eFiles 超出大小的文件
124+
// maxSize 文件大小最大值限制
125+
})
126+
// 生成分片前
127+
uploader.on('beforeChunk', qf => {
128+
})
129+
// 生成分片后
130+
uploader.on('beforeChunk', qf => {
131+
})
132+
// 生成文件hash值前
133+
uploader.on('beforeHash', qf => {
134+
})
135+
// 生成文件hash值后
136+
uploader.on('beforeHash', qf => {
137+
})
138+
// 进度事件
139+
uploader.on('progress', (ev, percent) => {
140+
// ev事件对象
141+
// percent 单个文件上传百分比
142+
})
143+
// 上传成功
144+
uploader.on('success', (qf,res,chunk) => {
145+
// qf 详见附录1
146+
// res 服务器返回结果
147+
// chunk分块上传时的分块
148+
})
149+
// 上传失败
150+
uploader.on('error', res => {
151+
// res 发生错误时的结果
152+
})
153+
```
154+
155+
## 附录1 options
156+
157+
options
158+
```js
159+
// 示例
160+
const uploader = new Uploader({
161+
inputElem: 'uploadInput', // 选择文件的元素
162+
triggerEvent: 'chuange', // 触发事件 默认change
163+
uploadUrl: '', // 文件上传路径
164+
name: 'file', // 上传的文件字段名
165+
hashFile: true, // 是否计算文件hash值 (默认md5)
166+
hashMethod: (file) => {
167+
// 可选计算文件hash值的方法,file为文件对象
168+
// 需返回一个Promise实例,并resolve计算后的hash值
169+
},
170+
uploadType: this.uploadType, // 分块上传时上传方式 0-并行上传 1-串行上传
171+
chunkSize: (qf) => 1 * 1024 * 1024, // 分块大小 单位byte 数值或function qf为队列文件
172+
headers: (info) => {
173+
// 请求头 键值对象或返回键值对象的function,info为分块信息
174+
return {
175+
// ...
176+
}
177+
},
178+
data: (info) => {
179+
// 上传时携带的数据,需返回一个对象
180+
return {
181+
// ...
182+
}
183+
},
184+
/** 检测文件上传状态方法 */
185+
checkMethod: (qf, resolve) => {
186+
// 请求文件上传状态
187+
// 调用 resolve 方法告知已上传分块,传参为数组 例:resolve([1,2,3])
188+
}
189+
})
190+
```
191+
## 附录2 文件状态
192+
即uploader.queue[0].status
193+
```js
194+
/** 队列文件状态 */
195+
export const QF_STATUS = {
196+
pending: 'pending', // 等待上传
197+
ready: 'ready', // 准备就绪
198+
hashing: 'hashing', // 正在计算hash值
199+
hashed: 'hashed', // 计算hash值完成
200+
chunking: 'chunking', // 正在进行文件分块
201+
chunked: 'chunked', // 文件分块完成
202+
checking: 'checking', // 检测文件状态
203+
checked: 'checked', // 检测文件状态完成
204+
uploading: 'uploading', // 正在上传
205+
abort: 'abort', // 中断
206+
success: 'success', // 上传成功
207+
error: 'error' // 上传失败
208+
}
209+
```
210+
211+
## 附录3 qf
212+
qf为保存在Uploader实例的queue属性(数组)中的对象,qf是QueueFile的实例
213+
```js
214+
qf = {
215+
file: null, // 原始文件对象
216+
fileHash: '', // 文件哈希值
217+
chunkSize: 0, // 分块大小
218+
chunks: [
219+
// 文件分块信息
220+
// {
221+
// index: 0, // 第几个分块
222+
// blob: null, // 分块bob数据
223+
// percent: 0, // 上传进度
224+
// uploaded: false // 是否已上传
225+
// }
226+
],
227+
percent: 0, // 上传百分比
228+
status: 'pending', // 状态 见附录2
229+
response: '' // 服务器返回
230+
// ...
231+
}
232+
233+
```
234+
235+
## 附录4 chunk
236+
文件分块信息,chunk是Chunk的实例
237+
```js
238+
class Chunk {
239+
queueFile // qf
240+
index = 0 // 分块索引
241+
blob // 分块blob数据
242+
percent = 0 // 上传百分比
243+
uploaded = false // 是否已经上传
244+
response = null // 服务器的返回值
245+
// ...
246+
}
247+
248+
```
249+
250+
## 附录5 info
251+
```js
252+
info = {
253+
file: null, // 原始文件对象
254+
fileHash: '', // 文件哈希值
255+
chunkSize: 0, // 分块大小
256+
chunks: [
257+
// 文件分块信息
258+
// {
259+
// index: 0, // 第几个分块
260+
// blob: null, // 分块bob数据
261+
// percent: 0, // 上传进度
262+
// uploaded: false // 是否已上传
263+
// }
264+
],
265+
percent: 0, // 上传百分比
266+
status: 'pending', // 状态 见附录2
267+
response: '', // 服务器返回
268+
chunk: null, // 分块的blob数据
269+
chunkIndex: 0 // 分块索引
270+
271+
// ...
272+
}
273+
274+
```
275+

build/rollup.config.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import babel from '@rollup/plugin-babel';
22
import resolve from 'rollup-plugin-node-resolve';
33
import commonjs from '@rollup/plugin-commonjs';
4+
//import babelrc from 'babelrc-rollup';
45
//import pkg from './package.json';
5-
// rollup.config.js
66
export default {
77
input: 'src/index.js',
88
output: {
@@ -13,6 +13,6 @@ export default {
1313
plugins: [
1414
resolve(),
1515
commonjs(),
16-
babel({ babelHelpers: 'bundled' })
16+
babel({babelHelpers:'runtime',plugins:['@babel/plugin-transform-runtime']})
1717
]
1818
};

0 commit comments

Comments
 (0)