webuploader 使用方法,webuploader官网文档 (不得不说,官网作者的语文学的不好,写的没有逻辑性,根本看不懂,抓不住要害,越看越晕,当然相信官网的材料是最新的,下载文件也不会有错误,仅此而已,学习还是要靠自己研究,原本以为一个周六周日可以搞定,结果啥也没搞明白 ... ... )补充:官网从这里开始:Get Start,官网函数手册查询:API 手册。如果不按这个顺序,肯定晕菜!(这几天摸索出来的。还有,那个“document”简直就是一个陷阱,本来第一招还没学明白,他又说了第二招,然后说一堆,似乎是很底层的东西,把我彻底说晕了,后来我觉得其实不要看这个“document”,因为我们一般人,学会一招就可以了,至于底层更不需要知道)
题外话:为了学习webuploader,我在百度上“云游四海”学了很多,晕了好几天,终于今天上道了。来整理一下笔记。
最小系统的练习
- 最小系统 - html // 最简单版,只设置一个按钮,选择文件直接上传 (省掉 "上传按钮",省掉 "预览div" )
<!-- html界面 -->
<div id="picker">选择文件</div> <!-- 最简单的,只有一个按钮,选择完文件直接上传(省掉了上传按钮)(也省掉了预览<div>) -->
<!-- 引入资源 -->
<link rel="stylesheet" type="text/css" href="../../0.1.5/webuploader.css" /> <!-- 引入webuploader.css文件(必须文件) -->
<script type="text/javascript" src="../../../jquery/3.2.1/jquery.min.js"></script> <!-- jquery3.2.1 js (webuploader.js的基础) -->
<script type="text/javascript" src="../../0.1.5/webuploader.js"></script> <!-- 引入webuploader.js文件(必须文件) -->
<script type="text/javascript" src="./upload.js"></script> <!-- 本程序的js代码 -->
- 最小系统 - upload.js //1、实例化uploader,连接 div - "选择文件", id = '#picker', server : 'fileupload.php' (服务器侧php接收端), //2、当用户点击"选择文件"按钮,选择要上传的文件,js立刻调用 uploader.on('fileQueued', function(file){ ... }); 为了简化代码,在此函数中,直接调用 uploader.upload() - 启动上传服务器。(由于webuploader不处理UI(user interface)逻辑,所以需要去监听fileQueued事件来实现。)
$(function(){
// uploader实例化,WebUploader.create()
var uploader = WebUploader.create({
swf: '../../0.1.5//Uploader.swf', // swf文件路径
server: '../../server-php/fileupload.php', // 文件接收服务端,保存在 /static/webuploader/server-php/
pick: '#picker', // 选择文件的按钮。可选。// 内部根据当前运行是创建,可能是input元素,也可能是flash.
resize: false // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
});
// 当有文件被添加进队列的时候,自动调用此函数
uploader.on('fileQueued', function(file){ //这里 file 是选中的文件,但本示例没有使用
uploader.upload(); //选择的文件上传到服务器
});
})
- 最小系统 - fileupload.php // 用了 webuploader 官网的示例文件,直接把 上传的文件 保存到 fileupload 当前文件下的 upload / *.* 如下图,上传成功
但系统有个“警告”,如下,不知道是啥原因
文件上传练习 - 官网demo
- 文件上传 - html
<!-- html界面 下面所有class都需要用户在自己的css里定义-->
<div id="uploader" class="wu-example"> <!-- uploader 区域 -->
<div id="thelist" class="uploader-list"></div> <!--用来存放文件信息 upload.js会在此区域自动生成div(file.id).h4(file.name).p(status)-->
<div class="btns"> <!-- uploader 按钮区 -->
<div id="picker">选择文件</div> <!-- 选择文件上传按钮,唯一 webuploader 管理css的元素 -->
<button id="ctlBtn" class="btn btn-default">开始上传</button> <!-- 启动上传按钮 这里class使用bootstrap式样-->
</div>
</div>
<!-- 引入资源 这部分和上面例子一样,不再重复-->
- 文件上传 - upload.js 文件上传失败会派送uploadError事件,成功则派送uploadSuccess事件。不管成功或者失败,在文件上传完后都会触发uploadComplete事件。文件上传中,Web Uploader会对外派送uploadProgress事件,其中包含文件对象和该文件当前上传进度。
$(function() {
// uploader实例化,WebUploader.create()
var uploader = WebUploader.create({
swf: '../../0.1.5//Uploader.swf', // swf文件路径
server: '../../server-php/fileupload.php', // 文件接收服务端,保存在 /static/webuploader/server-php/
pick: '#picker', // 选择文件的按钮。可选。// 内部根据当前运行是创建,可能是input元素,也可能是flash.
resize: false // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
});
// 当有文件被添加进队列的时候,监听程序调用此函数
uploader.on('fileQueued', function( file ){
$('#thelist').append( '<div id="' + file.id + '" class="item">' +
'<h4 class="info">' + file.name + '</h4>' +
'<p class="state">等待上传...</p>' +
'</div>' );
});
// 文件上传过程中创建进度条实时显示。
uploader.on('uploadProgress', function(file, percentage){
var $li = $( '#'+file.id ),
$percent = $li.find('.progress .progress-bar');
// 避免重复创建
if (!$percent.length){
$percent = $('<div class="progress progress-striped active">' +
'<div class="progress-bar" role="progressbar" style="width: 0%">' +
'</div>' +
'</div>').appendTo( $li ).find('.progress-bar');
}
$li.find('p.state').text('上传中');
$percent.css( 'width', percentage * 100 + '%' );
});
uploader.on('uploadSuccess', function(file){
$( '#'+file.id ).find('p.state').text('已上传');
});
uploader.on('uploadError', function(file){
$( '#'+file.id ).find('p.state').text('上传出错');
});
uploader.on('uploadComplete', function(file){
$( '#'+file.id ).find('.progress').fadeOut();
});
//官方文档就少了这段,我不能理解为啥少了这段,没有这段初学者肯定晕菜了,作者语文没学好,还是故意的,可是你写文档不就是让人学会吗?无法理解为啥!
$("#ctlBtn").click(function(){
uploader.upload();
});
})
- 运行结果如下:选择文件,则如左图,列出了file.name, status=等待上传... ; 点击上传后,如右图,各个文件的status=已上传; 到服务器文件夹 upload/下可以找到已经上传的文件。
=>
遗留问题,进度条,没看到,不知道为啥,是太快了?现在搞明白了,是确实css式样定义,所以增加文件:webuploader.ui.css (这部分,官网甚至都没提及,我百度出来的)
.progress {
height: 20px;
margin-bottom: 20px;
overflow: hidden;
background-color: #f5f5f5;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);
box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);
}
.progress.active .progress-bar {
-webkit-animation: progress-bar-stripes 2s linear infinite;
animation: progress-bar-stripes 2s linear infinite;
}
.progress-striped .progress-bar {
background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);
background-size: 40px 40px;
}
.progress-bar {
background-image: -webkit-linear-gradient(top,#428bca 0,#3071a9 100%);
background-image: linear-gradient(to bottom,#428bca 0,#3071a9 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=’#ff428bca’,endColorstr=’#ff3071a9’,GradientType=0);
}
.progress-bar {
float: left;
height: 100%;
font-size: 12px;
line-height: 20px;
color: #fff;
text-align: center;
background-color: #428bca;
box-shadow: inset 0 -1px 0 rgba(0,0,0,0.15);
transition: width .6s ease;
}
下面学习 webuploader 丰富多彩的功能
- 选择上传文件的文字提示,可以在create() 函数设置。 (此 pick{} 还有一个参数 multiple {Boolean} 是否开起同时选择多个文件能力
uploader = WebUploader.create({
pick: { // 选择文件的按钮。可选。// 内部根据当前运行是创建,可能是input元素,也可能是flash.
id: '#filePicker',
innerHTML: '点击选择图片'// 指定按钮文字。不指定时优先从指定的容器中看是否自带文字。
},
});
- 拖拽图片进入上传区域,
uploader = WebUploader.create({
disableGlobalDnd: true, // 禁掉全局的拖拽功能。这样不会出现图片拖进页面的时候,浏览器把图片打开,无法让webuploader收到图片。
dnd: '#uploader .queueList', // 拖拽进入的区域
});
- past 指定监听paste事件的容器,如果不指定,不启用此功能。此功能为通过粘贴来添加截屏的图片,但我测试失败了,不知道失败原因 ???
uploader = WebUploader.create({
paste: '#uploader', //指定监听paste事件的容器,如果不指定,不启用此功能。此功能为通过粘贴来添加截屏的图片。
});
- 指定接受哪些类型的文件,accept {Arroy} [可选] [默认值:null] 由于目前还有ext转mimeType表,所以这里需要分开指定。// title {String} 文字描述 // extensions {String} 允许的文件后缀,不带点,多个用逗号分割。// mimeTypes {String} 多个用逗号分割。
uploader = WebUploader.create({
accept: {
title: 'Images', //文件类型的文字描述
extensions: 'gif,jpg,jpeg,bmp,png', //允许的文件后缀,不带点,多个用逗号分割。
mimeTypes: 'image/*' // 含义不太清晰?? 多个用逗号分割
},
});
- 大文件分片上传:chunked {Boolean} [可选] [默认值:false] 是否要分片处理大文件上传。 // chunkSize {int} [可选] [默认值:5242880] 如果要分片,分多大一片? 默认大小为5M. // chunkRetry {int} [可选] [默认值:2] 如果某个分片由于网络问题出错,允许自动重传多少次?
uploader = WebUploader.create({
chunked: false, // 是否要分片处理大文件上传
chunkSize: 512 * 1024, //如果要分片,分多大一片?默认大小5M(5242880)
chunkRetry: 2, //如果某个分片由于网络原因出错,允许自动重传多少次?默认2次
});
- thumb {Object} [可选] 配置生成缩略图的选项。
// 默认值
thumb: {
width: 110,
height: 110,
quality: 70, // 图片质量,只有type为`image/jpeg`的时候才有效。
allowMagnify: true, // 是否允许放大,如果想要生成小图的时候不失真,此选项应该设置为false.
crop: true, // 是否允许裁剪。
type: 'image/jpeg' // 为空的话则保留原有图片格式。// 否则强制转换成指定的类型。
}
- compress {Object} [可选] 配置压缩的图片的选项。如果此选项为false, 则图片在上传前不进行压缩。
// 默认值
compress: {
width: 1600,
height: 1600,
quality: 90, // 图片质量,只有type为`image/jpeg`的时候才有效。
allowMagnify: false, // 是否允许放大,如果想要生成小图的时候不失真,此选项应该设置为false.
crop: false, // 是否允许裁剪。
preserveHeaders: true, // 是否保留头部meta信息。
noCompressIfLarger: false, // 如果发现压缩后文件大小比原来还大,则使用原来图片 // 此属性可能会影响图片自动纠正功能
compressSize: 0 // 单位字节,如果图片大小小于此值,不会采用压缩。
}
- formData {Object} [可选] [默认值:{}] 文件上传请求的参数表,每次发送都会发送此对象中的参数。
uploader = WebUploader.create({
formData: {
uid: 123 //文件上传请求的参数表,每次发送都会发送此对象中的参数
},
});
- 其他create() 设置值:
- Uploader类的常用方法:
- uploader.on(name, callback[, context] ) ⇒ self
- 当有文件被添加(按钮添加或者拖拽添加)进入上传队列时,调用此函数 (与此函数类似的,还有 uploader.on( 'filesQueued', function( file ) { ... }), 当一批文件添加进队列以后触发。执行顺序:首先执行filesQueued函数 - 例如一次添加3个图片文件,然后分3次调用fileQueued 函数,所以如果无特殊需要,只处理 fileQueued函数即可)
回调函数function(file) 参数 file:File对象
// 当有文件被添加进队列的时候
uploader.on( 'fileQueued', function( file ) {
$list.append( '<div id="' + file.id + '" class="item"><h4 class="info">' + file.name + '</h4><p class="state">等待上传...</p></div>' ); //
});
- 这个版本函数更简洁 & 快捷,推荐使用这种形式
// 当有文件被添加进队列的时候, 这个版本函数更简介 & 快捷,推荐使用这种形式
uploader.onFileQueued = function( file ) {
$list.append( '<div id="' + file.id + '" class="item"><h4 class="info">' + file.name + '</h4><p class="state">等待上传...</p></div>' ); //
};
- 当文件被移除队列后触发。官方文档:uploader.on('fileDequeued', function(file) { ... }) // 参数:file {File}File对象 但推荐用下面函数,更简洁 & 清晰
回调函数function(file) 参数 file:File对象
//当文件被移除队列后,自动调用这个函数
uploader.onFileDequeued = function(file){
fileCount--;
fileSize -= file.size;
if(!fileCount){
setState( 'pedding' );
}
removeFile(file);
updateTotalProgress();
};
- 上传过程中反复调用此函数,实现进度条功能。//快捷函数:
回调函数function(file) 参数 1、file {File}:File对象,参数 2、percentage {Number}:上传进度
// 文件上传过程中创建进度条实时显示。
uploader.on( 'uploadProgress', function( file, percentage ) {
var $li = $( '#'+file.id ), $percent = $li.find('.progress .progress-bar');
// 避免重复创建
if ( !$percent.length ) {
$percent = $('<div class="progress progress-striped active"><div class="progress-bar" role="progressbar" style="width: 0%"></div></div>').appendTo( $li ).find('.progress-bar');
}
$li.find('p.state').text('上传中');
$percent.css( 'width', percentage * 100 + '%' );
});
- 这个版本函数更简洁 & 快捷,推荐使用这种形式
// 文件上传过程中创建进度条实时显示。
uploader.onUploadProgress = function(file, percentage){
var $li = $('#'+file.id),
$percent = $li.find('.progress span');
$percent.css('width', percentage * 100 + '%');
percentages[ file.id ][ 1 ] = percentage;
updateTotalProgress();
};
- 过程状态:// 'all', 用uploader.on('all', function(type){ ... } 处理所有上传过程的消息函数 & 回调函数,虽然不推荐这么做,但你可以尝试一下。
// 文件上传开始/暂停/完成状态提取&展示
uploader.on('all', function(type){
switch(type){
case 'startUpload': //"startUpload": 开始上传
setState('uploading'); //
break; //
case 'stopUpload': //"stopUpload": 上传暂停
setState('paused'); //
break; //
case 'uploadFinished': //"uploadFinished": 上传完成
setState('confirm'); //
break; //
}
});
- 过程状态:分解为详细的各个消息函数 & 回调函数,执行顺序如下:
- 1、文件开始上传,派送startUpload事件:uploader.onStartUpload = function(){ ... }; // 参数:无
// 上传消息1:文件上传开始
uploader.onStartUpload = function(){
setState('uploading');
alert("onStartUpload");
};
- 1.5 文件上传过程中发出暂停命令 - uploader.stop(); 派送stopUpload事件:uploader.onStopUpload = function(){ ... }; // 参数:无
// 上传消息1.5:文件上传过程中如果发生暂停
uploader.onStopUpload = function(){
setState('paused');
alert("onStopUpload");
};
- 2.1 文件上传成功则派送uploadSuccess事件:uploader.onUploadSuccess = function(file, response){ ... }; // 参数 1、file {File}File对象;参数 2、response {Object}服务端返回的数据
//上传消息2.1:文件上传成功后调用此函数 onUploadSuccess
uploader.onUploadSuccess = function(file, response){
console.log(response);
alert("onUploadSuccess");
//$( '#'+file.id ).find('p.state').text('已上传');
};
- 2.2 文件上传失败会派送uploadError事件:uploader.onUploadError = function(file, reason){ ... }; // 参数 1、file {File}File对象;参数 2、reason {String}出错的code
//上传消息2.2:文件上传失败后调用此函数 onUploadError
uploader.onUploadError = function(file, reason){
console.log(reason);
alert("onUploadError");
//$( '#'+file.id ).find('p.state').text('已上传');
};
- 3 文件上传完成后,不管成功或者失败,都会触发uploadComplete事件:uploader.onUploadComplete = function(file){ ... }; // 参数 file {File} [可选]File对象
//3 文件上传完成后,不管成功还是失败,调用完上面两个函数之一后调用此函数 uploadComplete
uploader.onUploadComplete = function(file){
console.log(file);
alert("onUploadComplete");
// $( '#'+file.id ).find('.progress').fadeOut();
};
- 4 当所有文件上传结束时触发: uploader.onUploadFinished = function(){ ... }; // 参数:无
//4 文件上传完成状态
uploader.onUploadFinished = function(){
alert("uploadFinished");
setState('confirm');
};
- 老的方式 (官网介绍,不推荐使用)
uploader.on('uploadSuccess', function(file, response){
$( '#'+file.id ).find('p.state').text('已上传');
}); //文件上传成功后调用此函数 uploadSuccess
uploader.on('uploadError', function(file, reason){
$( '#'+file.id ).find('p.state').text('上传出错');
}); //文件上传失败后调用此函数 uploadError
uploader.on('uploadComplete', function(file){
$( '#'+file.id ).find('.progress').fadeOut();
}); //文件上传完成后,不管成功还是失败,调用完上面两个函数之一后调用此函数 uploadComplete
- uploader.on('dndAccept', function( items ) { ... }) 阻止此事件可以拒绝某些类型的文件拖入进来。目前只有 chrome 提供这样的 API,且只能通过 mime-type 验证。
// 下面举例:拖拽时不接受 js, txt 文件
uploader.on('dndAccept', function( items ) {
var denied = false,
len = items.length,
i = 0,
// 修改js类型
unAllowed = 'text/plain;application/javascript ';
for ( ; i < len; i++ ) {
// 如果在列表里面
if ( ~unAllowed.indexOf( items[ i ].type ) ) {
denied = true;
break;
}
}
return !denied;
});
- 其他 .on(" ... ", function(){ ... }); 事件
uploader.on('beforeFileQueued', function(file) { ... }) // 参数:file {File}File对象 //当文件被加入队列之前触发,此事件的handler返回值为false,则此文件不会被添加进入队列。
uploader.on('reset', function() { ... }) // 参数:无 //当 uploader 被重置的时候触发。
uploader.on('uploadStart', function(file) { ... }) // 参数:file {File}File对象 //某个文件开始上传前触发,一个文件只会触发一次。
uploader.on('uploadBeforeSend', function(object, data, headers) { ... }) //当某个文件的分块在发送前触发,主要用来询问是否要添加附带参数,大文件在开起分片上传的前提下此事件可能会触发多次。
// 参数:object {Object} data {Object}默认的上传参数,可以扩展此对象来控制上传参数。 headers {Object}可以扩展此对象来控制上传头部。 uploader.on('uploadAccept', function(object, ret) { ... }) //当某个文件的分块在发送前触发,主要用来询问是否要添加附带参数,大文件在开起分片上传的前提下此事件可能会触发多次。
// 参数:
- object {Object}
- ret {Object}服务端的返回数据,json格式,如果服务端不是json格式,从ret._raw中取数据,自行解析。
uploader.on('error', function(type) { ... }) // 参数:type {String}错误类型。 //当validate不通过时,会以派送错误事件的形式通知调用者。通过upload.on('error', handler)可以捕获到此类错误,
目前有以下错误会在特定的情况下派送错来。
- Q_EXCEED_NUM_LIMIT 在设置了fileNumLimit且尝试给uploader添加的文件数量超出这个值时派送。
- Q_EXCEED_SIZE_LIMIT 在设置了Q_EXCEED_SIZE_LIMIT且尝试给uploader添加的文件总大小超出这个值时派送。
- Q_TYPE_DENIED 当文件类型不满足时触发。。
uploader.on( 'all', function( type ) {
var stats;
switch( type ) {
case 'uploadFinished':
setState( 'confirm' );
break;
case 'startUpload':
setState( 'uploading' );
break;
case 'stopUpload':
setState( 'paused' );
break;
}
});
uploader.onError = function( code ) { alert( 'Eroor: ' + code );
};
- upload() 开始上传。此方法可以从初始状态调用开始上传流程,也可以从暂停状态调用,继续上传流程。可以指定开始某一个文件。
upload() ⇒ undefined
upload( file | fileId) ⇒ undefined
- stop() //暂停上传。第一个参数为是否中断上传当前正在上传的文件。如果第一个参数是文件,则只暂停指定文件。
stop() ⇒ undefined
stop( true ) ⇒ undefined
stop( file ) ⇒ undefined
- cancelFile() //参数: file {File, id}File对象或这File对象的id 标记文件状态为已取消, 同时将中断文件传输。
cancelFile( file ) ⇒ undefined
cancelFile( id ) ⇒ undefined
$li.on('click', '.remove-this', function() {
uploader.cancelFile( file );
})
- isInProgress() //判断Uplaoder是否正在上传中。
isInProgress() ⇒ Boolean
- skipFile() //跳过一个文件上传,直接标记指定文件为已上传状态。
skipFile( file ) ⇒ undefined
- retry() //重试上传,重试指定文件,或者从出错的文件开始重新上传。
retry() ⇒ undefined
retry( file ) ⇒ undefined
function retry() {
uploader.retry();
}
- sort() //排序队列中的文件,在上传之前调整可以控制上传顺序
sort( fn ) ⇒ undefined
- addFiles() //添加文件到队列
参数:files {Array of File or File} [可选]Files 对象 数组
addFiles( file ) ⇒ undefined
addFiles( [file1, file2 ...] ) ⇒ undefined
- removeFile() //移除某一文件, 默认只会标记文件状态为已取消,如果第二个参数为 true 则会从 queue 中移除。
参数: file {File, id}File对象或这File对象的id
removeFile( file ) ⇒ undefined
removeFile( id ) ⇒ undefined
removeFile( file, true ) ⇒ undefined
removeFile( id, true ) ⇒ undefined
$li.on('click', '.remove-this', function() {
uploader.removeFile( file );
})
- getFiles() //返回指定状态的文件集合,不传参数将返回所有状态的文件。
getFiles() ⇒ Array
getFiles( status1, status2, status... ) ⇒ Array
console.log( uploader.getFiles() ); // => all files
console.log( uploader.getFiles('error') ) // => all error files.
- getStats() //获取文件统计信息。返回一个包含一下信息的对象。
getStats() ⇒ Object {
successNum 上传成功的文件数
progressNum 上传中的文件数
cancelNum 被删除的文件数
invalidNum 无效的文件数
uploadFailNum 上传失败的文件数
queueNum 还在队列中的文件数
interruptNum 被暂停的文件数
}
- destroy() ⇒ undefined // 销毁 webuploader 实例
- addButton( pick ) ⇒ Promise // 添加文件选择按钮,如果一个按钮不够,需要调用此方法来添加。参数跟options.pick一致。
uploader.addButton({
id: '#btnContainer',
innerHTML: '选择文件'
});
- makeThumb() //生成缩略图,此过程为异步,所以需要传入callback。 通常情况在图片加入队里后调用此方法来生成预览图以增强交互效果。
makeThumb( file, callback ) ⇒ undefined
makeThumb( file, callback, width, height ) ⇒ undefined
uploader.on( 'fileQueued', function( file ) {
var $li = ...;
uploader.makeThumb( file, function( error, ret ) {
if ( error ) {
$li.text('预览错误');
} else {
$li.append('<img alt="" src="' + ret + '" />');
}
});
});
以上来自官网的示例代码,其实展示不够清晰。下面是来自实际案例的代码:
var ratio = window.devicePixelRatio || 1, // 优化retina, 在retina下这个值是2
thumbnailWidth = 110 * ratio, // 缩略图大小
thumbnailHeight = 110 * ratio; // 缩略图大小
uploader.makeThumb(file, function(error, src){
var img;
if(error){
$wrap.text( '不能预览' );
return;
}
if(isSupportBase64) {
img = $('<img src="'+src+'">');
$wrap.empty().append( img ); //empty()移除被选元素的所有子节点和内容
}else{
$.ajax('./preview.php', {
method: 'POST',
data: src,
dataType:'json'
}).done(function( response ) {
if (response.result) {
img = $('<img src="'+response.result+'">');
$wrap.empty().append( img );
}else{
$wrap.text("预览出错");
}
});
}
}, thumbnailWidth, thumbnailHeight );
- md5File( file[, start[, end]] ) ⇒ promise //计算文件 md5 值,返回一个 promise 对象,可以监听 progress 进度。
uploader.on( 'fileQueued', function( file ) {
var $li = ...;
uploader.md5File( file )
// 及时显示进度
.progress(function(percentage) {
console.log('Percentage:', percentage);
})
// 完成
.then(function(val) {
console.log('md5 result:', val);
});
});
- File类的常用方法
- new File(source) ⇒ File // 构造函数
参数: source {Lib.File}lib.File实例, 此source对象是带有Runtime信息的。
- .on() 事件:on('statuschange', function(cur, prev){ ... }) // 文件状态变化时,调用此函数
cur or prev (File.Status):文件状态值有8种状态,具体包括以下几种类型:
- inited 初始状态 (文件添加后)
- queued 已经进入队列, 等待上传 (点击 "文件上传" 按钮)
- progress 上传中 (此文件开始上传)
- complete 上传完成。(此文件上传完成,这时候要在onUploadSuccess()里设置变量percentages[file.id][2] = true,才说明确实上传成功,否则未必真的上传成功)
- error 上传出错,可重试
- interrupt 上传中断,可续传。
- invalid 文件不合格,不能重试上传。会自动从队列中移除。
- cancelled 文件被移除。
1、file 创建之初 (初始状态),cur = inited,并不触发 "statuschange" 事件 (prev = null)
2、点击 "文件上传" 按钮,触发 "statuschange" 事件:cur = queued,prev = inited // 含义:此文件已经进入队列,准备要上传
3、当此文件在上传队列里排队,排到了上传的时刻,则再次触发 "statuschange" 事件:cur = progress,prev = queued // 此文件开始上传
4、当上传出错时,再次触发 "statuschange" 事件:cur = error,prev = progress// 报告:此文件上传失败,file.statusText 装载着错误信息,和 uploader.onUploadError = function(file, reason){ ... }; 里面 reason 的信息一样;(有趣的是:php里调用语句:“header("HTTP/1.0 500 Internal Server Error"); exit;”,则触发 “上传出错” 消息处理机制 )
多大
file.on('statuschange', function( cur, prev ) {
if ( prev === 'progress' ) {
$prgress.hide().width(0);
} else if ( prev === 'queued' ) {
$li.off( 'mouseenter mouseleave' );
$btns.remove();
}
// 成功
if ( cur === 'error' || cur === 'invalid' ) {
console.log( file.statusText );
showError( file.statusText );
percentages[ file.id ][ 1 ] = 1;
} else if ( cur === 'interrupt' ) {
showError( 'interrupt' );
} else if ( cur === 'queued' ) {
$info.remove();
$prgress.css('display', 'block');
percentages[ file.id ][ 1 ] = 0;
} else if ( cur === 'progress' ) {
$info.remove();
$prgress.css('display', 'block');
} else if ( cur === 'complete' ) {
$prgress.hide().width(0);
$li.append( '<span class="success"></span>' );
}
$li.removeClass( 'state-' + prev ).addClass( 'state-' + cur );
});
- File类属性
id: 文件ID,每个对象具有唯一ID,与文件名无关
name: 文件名,包括扩展名(后缀)
ext: 文件扩展名,通过文件名获取,例如test.png的扩展名为png
size:文件体积(字节)
type: 文件MIMETYPE类型,与文件类型的对应关系请参考http://t.cn/z8ZnFny
lastModifiedDate: 文件最后修改日期
statusText: 状态文字说明。在不同的status语境下有不同的用途。
File.Status:文件状态值,共8种,具体参考上面介绍的 - .on() 事件:on('statuschange', function(cur, prev){ ... })
- setStatus( status[, statusText] ); //设置状态,状态变化时会触发change事件。
参数:
status {File.Status, String}文件状态值
statusText {String} [可选] [默认值: ''] 状态说明,常在error时使用,用http, abort,server等来标记是由于什么原因导致文件错误。
- getStatus(); //
if(file.getStatus() === 'invalid') {
showError(file.statusText);
}else{
...
}
- Queue类的常用方法 // 文件队列, 用来存储各个状态中的文件。
- stats
统计文件数。
- numOfQueue 队列中的文件数。
- numOfSuccess 上传成功的文件数
- numOfCancel 被取消的文件数
- numOfProgress 正在上传中的文件数
- numOfUploadFailed 上传错误的文件数。
- numOfInvalid 无效的文件数。
- numofDeleted 被移除的文件数。
- append // 参数: file {File}文件对象 // 将新文件加入对队列尾部
- prepend // 参数: file {File}文件对象 // 将新文件加入对队列头部
- getFile // 参数: fileId {String}文件ID 返回值: {File} // 获取文件对象
- fetch // fetch( status ) ⇒ File // 参数: status {String}文件状态值 返回值: {File}File // 从队列中取出一个指定状态的文件。
- sort // sort( fn ) ⇒ undefined // 参数: fn {Function}排序方法 // 对队列进行排序,能够控制文件上传顺序。
- getFiles // getFiles( [status1[, status2 ...]] ) ⇒ Array // 参数: status {String} [可选]文件状态值 // 获取指定类型的文件列表, 列表中每一个成员为File对象。
- removeFile // removeFile( file ) ⇒ Array // 参数: 文件对象。 {File} // 在队列中删除文件。
- 下面我们来研究一下 server 文件(php)
- lesson learn: php 中使用 exit; 返回后,前端仍然调用 uploader.onUploadSuccess() 反馈上传成功!
- 建议返回采用:die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}'); // 前端js调用 uploader.onUploadSuccess = function(file, response){ ... }; 用 response 接受 die(' ... ') 发过来的信息。所有我们有机会,针对 php (server侧)不同返回情况,做成正确的反应。
- 这里“官网”的php server文件示例里用了 jsonrpc2.0,我学习了一下什么是 jsonrpc2.0 可以参考:我的jsonrpc2.0学习笔记 ,学习后发现,jsonrpc2.0并不适合webuploader,用牛刀杀鸡,大量代码都用不上,而且demo文件里也没有正确使用 jsonrpc2.0. 所以最后我决定还是采用 "信息反馈格式" (information feed back from server - template), 和 $ajax 一样的格式,这样标准化也好一些。
$ajax_data["err"] = 1;
$ajax_data["msg"] = "发生try{}catch错误,catch-$ex.message=".$ex->getMessage();
$ajax_data["data"] = $data;
die(json_encode($ajax_data));
- 有趣的是:php里调用语句:“header("HTTP/1.0 500 Internal Server Error"); exit;”,则触发 “上传出错” 消息处理机制,1、首先触发:on('statuschange', function(cur, prev){ ... }) cur = “error”,并且 file.statusText 装载着错误信息,2、随后触发:uploader.onUploadError = function(file, reason){ ... }; reason 装载错误信息。
这里 HTTP1.0 500,500的含义,其他代码说明,请参考:HTTP 1.1状态代码及其含义