最近在做一个内部系统,需要一个无刷新的上传功能,找了许久,发现了一个好用的上传工具-Fine Uploader,网上也有不少关于它的介绍,对我有不少的启发,结合我的使用场景简单的介绍一下它与thinkjs完美配合。
 
    首先就是使用thinkjs快速搭建一个web应用,可以参考之前写的一个thinkjs初试
 
    访问127.0.0.1:8360查看应用是否正常启动,如果一切正常就可以开始创建前端页面和服务端处理上传的逻辑的页面了。
 
    修改/App/Lib/Controller/Home/IndexController.js内容为:
   

/**
* controller
* @return
*/
module.exports = Controller("Home/BaseController", function(){
"use strict";
return {
indexAction: function(){
this.display();
},
uploadFileAction: function() {
var self = this;
var fileInfo = this.file('qqfile');
//http://www.thinkjs.org/doc/http.html#上传的文件
/*
//fileInfo的值
{
fieldName: 'qqfile',
originalFilename: '1.jpg',
path: '/home/maoshuai/htdocs/mtyras/App/Runtime/Temp/23886-1c2xozp.jpg',
headers:
{ 'content-disposition': 'form-data; name="qqfile"; filename="1.jpg"',
'content-type': 'image/jpeg' },
ws:
{ _writableState:
{ highWaterMark: 16384,
objectMode: false,
needDrain: false,
ending: true,
ended: true,
finished: true,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
sync: false,
bufferProcessing: false,
onwrite: [Function],
writecb: null,
writelen: 0,
buffer: [],
errorEmitted: false },
writable: true,
domain: null,
_events: { error: [Object], close: [Object] },
_maxListeners: 10,
path: '/home/maoshuai/htdocs/mtyras/App/Runtime/Temp/23886-1c2xozp.jpg',
fd: null,
flags: 'w',
mode: 438,
start: undefined,
pos: undefined,
bytesWritten: 28618,
closed: true },
size: 28618
}*/
if(fileInfo) {
self.json({
error: 0,
errmsg: 'ok',
success: true //只有success返回true才认为上传成功
});
}else {
self.error();
}
}
};
});
    修改/App/View/Home/index_index.html内容为:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="http://s7.qhimg.com/!f33a50ea/fine-uploader.css">
<title>Fine Uploader与thinkjs的邂逅</title>
</head>
<body>
<div id="fine-uploader-wrapper">
<div class="qq-uploader-selector qq-uploader">
<div class="qq-total-progress-bar-container-selector qq-total-progress-bar-container">
<div class="qq-total-progress-bar-selector qq-progress-bar qq-total-progress-bar"></div>
</div>
<div class="qq-upload-drop-area-selector qq-upload-drop-area" qq-hide-dropzone>
<span>拖拽上传区域</span>
</div>
<div class="qq-upload-button-selector qq-upload-button">
<div>选择文件</div>
</div>
<span class="qq-drop-processing-selector qq-drop-processing">
<span>上传进度</span>
<span class="qq-drop-processing-spinner-selector qq-drop-processing-spinner"></span>
</span>
<ul class="qq-upload-list-selector qq-upload-list">
<li>
<div class="qq-progress-bar-container-selector">
<div class="qq-progress-bar-selector qq-progress-bar"></div>
</div>
<span class="qq-upload-spinner-selector qq-upload-spinner"></span>
<span class="qq-edit-filename-icon-selector qq-edit-filename-icon"></span>
<span class="qq-upload-file-selector qq-upload-file"></span>
<input class="qq-edit-filename-selector qq-edit-filename" tabindex="0" type="text">
<span class="qq-upload-size-selector qq-upload-size"></span>
<a class="qq-upload-cancel-selector qq-upload-cancel" href="#">取消</a>
<a class="qq-upload-retry-selector qq-upload-retry" href="#">重试</a>
<a class="qq-upload-delete-selector qq-upload-delete" href="#">删除</a>
<span class="qq-upload-status-text-selector qq-upload-status-text"></span>
</li>
</ul>
</div>
</div>
<button id="upload-btn">上传按钮</button>
<script type="text/javascript" src="http://s8.qhimg.com/!240a7702/fine-uploader.js"></script>
<script type="text/javascript">
//具体参数参考源码qq.FineUploaderBasic中的_options查看
var uploader = new qq.FineUploader({
element: document.getElementById("fine-uploader-wrapper"), //上传按钮
request: {
endpoint: 'test/uploadFile' //上传接口地址
},
multiple: false, //是否多个文件
autoUpload: false, //是否支持上传
validation: {
allowedExtensions: ['jpeg', 'jpg', 'png'], //上传文件约束条件
sizeLimit: 2048000 //bytes 2000KB
},
callbacks: {
onSubmit: function(id, fileName) {
//文件开始提交
console.log(fileName,'文件开始提交');
},
onUpload: function(id, fileName) {
//文件开始上传
console.log(fileName,'文件开始提交');
},
onProgress: function(id, fileName, loaded, total) {
//文件正在上传
console.log(fileName,'已上传'+(loaded/total)*100+'%');
},
onComplete: function(id, fileName, responseJSON) {
//文件上传成功
console.log(fileName,'上传成功,返回信息为:',responseJSON);
},
onCancel: function(id, fileName) {
//取消文件上传
console.log('取消',fileName,'上传');
}
},
messages: {
noFilesError: '没有选中文件'
},
text: {
formatProgress: "{percent}% of {total_size}",
failUpload: "上传失败",
waitingForResponse: "上传中...",
paused: "暂停"
},
template: 'fine-uploader-wrapper', //ID
debug: true
}); document.getElementById('upload-btn').onclick = function() {
uploader.uploadStoredFiles();
}
</script>
</body>
</html>
    下面对服务端代码和前端页面进行详细的说明:
 
    服务端IndexController.js
    
    indexAction对应的页面是index_index.html,uploadFileAction对应的是前端页面的上传图片的接口,其中注释部分是通过thinkjs获取的文件信息,例子是直接返回了,使用的时候可以根据自己的情况,对上传的数据进行条件判断,然后做出相应的处理。这里需要注意的是:Fine Uploader返回的信息中必须包含success字段,并且只有在success=true的时候,才认为是上传成功,才会改变前端页面的展示。而thinkjs的this.success()函数不能传success参数,所以说使用了this.json()来实现。
 
    前端index_index.html
 
    页面没有要说的,主要介绍一下Fine Uploader的使用吧。
 
    它主要两种主要形式,一种是原生JS实现,一种是jquery插件形式,两种的使用方式分别如下:
   

$(dom).fineUploader(conf);
new qq.FineUploader(conf);

  

    接下来说一下conf可以配置什么信息,查看源码可以发现这个默认配置:

     this._options = {
debug: false,
button: null,
multiple: true,
maxConnections: 3,
disableCancelForFormUploads: false,
autoUpload: true, request: {
endpoint: "/server/upload",
params: {},
paramsInBody: true,
customHeaders: {},
forceMultipart: true,
inputName: "qqfile",
uuidName: "qquuid",
totalFileSizeName: "qqtotalfilesize",
filenameParam: "qqfilename"
}, validation: {
allowedExtensions: [],
sizeLimit: 0,
minSizeLimit: 0,
itemLimit: 0,
stopOnFirstInvalidFile: true,
acceptFiles: null,
image: {
maxHeight: 0,
maxWidth: 0,
minHeight: 0,
minWidth: 0
}
}, callbacks: {
onSubmit: function(id, name) {},
onSubmitted: function(id, name) {},
onComplete: function(id, name, responseJSON, maybeXhr) {},
onAllComplete: function(successful, failed) {},
onCancel: function(id, name) {},
onUpload: function(id, name) {},
onUploadChunk: function(id, name, chunkData) {},
onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},
onResume: function(id, fileName, chunkData) {},
onProgress: function(id, name, loaded, total) {},
onTotalProgress: function(loaded, total) {},
onError: function(id, name, reason, maybeXhrOrXdr) {},
onAutoRetry: function(id, name, attemptNumber) {},
onManualRetry: function(id, name) {},
onValidateBatch: function(fileOrBlobData) {},
onValidate: function(fileOrBlobData) {},
onSubmitDelete: function(id) {},
onDelete: function(id) {},
onDeleteComplete: function(id, xhrOrXdr, isError) {},
onPasteReceived: function(blob) {},
onStatusChange: function(id, oldStatus, newStatus) {},
onSessionRequestComplete: function(response, success, xhrOrXdr) {}
}, messages: {
typeError: "{file} has an invalid extension. Valid extension(s): {extensions}.",
sizeError: "{file} is too large, maximum file size is {sizeLimit}.",
minSizeError: "{file} is too small, minimum file size is {minSizeLimit}.",
emptyError: "{file} is empty, please select files again without it.",
noFilesError: "No files to upload.",
tooManyItemsError: "Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.",
maxHeightImageError: "Image is too tall.",
maxWidthImageError: "Image is too wide.",
minHeightImageError: "Image is not tall enough.",
minWidthImageError: "Image is not wide enough.",
retryFailTooManyItems: "Retry failed - you have reached your file limit.",
onLeave: "The files are being uploaded, if you leave now the upload will be canceled.",
unsupportedBrowserIos8Safari: "Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues."
}, retry: {
enableAuto: false,
maxAutoAttempts: 3,
autoAttemptDelay: 5,
preventRetryResponseProperty: "preventRetry"
}, classes: {
buttonHover: "qq-upload-button-hover",
buttonFocus: "qq-upload-button-focus"
}, chunking: {
enabled: false,
concurrent: {
enabled: false
},
mandatory: false,
paramNames: {
partIndex: "qqpartindex",
partByteOffset: "qqpartbyteoffset",
chunkSize: "qqchunksize",
totalFileSize: "qqtotalfilesize",
totalParts: "qqtotalparts"
},
partSize: 2000000,
// only relevant for traditional endpoints, only required when concurrent.enabled === true
success: {
endpoint: null
}
}, resume: {
enabled: false,
recordsExpireIn: 7, //days
paramNames: {
resuming: "qqresume"
}
}, formatFileName: function(fileOrBlobName) {
if (fileOrBlobName !== undefined && fileOrBlobName.length > 33) {
fileOrBlobName = fileOrBlobName.slice(0, 19) + "..." + fileOrBlobName.slice(-14);
}
return fileOrBlobName;
}, text: {
defaultResponseError: "Upload failure reason unknown",
sizeSymbols: ["kB", "MB", "GB", "TB", "PB", "EB"]
}, deleteFile: {
enabled: false,
method: "DELETE",
endpoint: "/server/upload",
customHeaders: {},
params: {}
}, cors: {
expected: false,
sendCredentials: false,
allowXdr: false
}, blobs: {
defaultName: "misc_data"
}, paste: {
targetElement: null,
defaultName: "pasted_image"
}, camera: {
ios: false, // if ios is true: button is null means target the default button, otherwise target the button specified
button: null
}, // This refers to additional upload buttons to be handled by Fine Uploader.
// Each element is an object, containing `element` as the only required
// property. The `element` must be a container that will ultimately
// contain an invisible `<input type="file">` created by Fine Uploader.
// Optional properties of each object include `multiple`, `validation`,
// and `folders`.
extraButtons: [], // Depends on the session module. Used to query the server for an initial file list
// during initialization and optionally after a `reset`.
session: {
endpoint: null,
params: {},
customHeaders: {},
refreshOnReset: true
}, // Send parameters associated with an existing form along with the files
form: {
// Element ID, HTMLElement, or null
element: "qq-form", // Overrides the base `autoUpload`, unless `element` is null.
autoUpload: false, // true = upload files on form submission (and squelch submit event)
interceptSubmit: true
}, // scale images client side, upload a new file for each scaled version
scaling: {
// send the original file as well
sendOriginal: true, // fox orientation for scaled images
orient: true, // If null, scaled image type will match reference image type. This value will be referred to
// for any size record that does not specific a type.
defaultType: null, defaultQuality: 80, failureText: "Failed to scale", includeExif: false, // metadata about each requested scaled version
sizes: []
}, workarounds: {
iosEmptyVideos: true,
ios8SafariUploads: true,
ios8BrowserCrash: true
}
};
    我们可以看到有很多很多的配置,大部分我也没有仔细的研究,只是看了一下常用的一些配置,并且在index_index.html也做了备注。我们关注的比较多的就是:multiple、autoUpload、validation、callbacks、messages、template,基本上这些就能满足我们的需求了。下面详解一下这几个参数的作用:
  • multiple是否支持多文件上传
  • autoUpload是否自动上传,就是说选中文件后,是否还需要手动点击上传按钮触发开始上传事件
  • validation文件约束条件,包含文件格式、文件最大值、文件最小值
  • callbacks各种回调函数,包含开始提交、开始上传、正在上传、上传成功、取消上传
  • messages一些默认提示信息,可以将源文件的错误提示汉化调整,例子中只是i调整了noFilesError,业务可以根据自己需求进行配置
  • template可以使用script模版或者dom模版,只要传模版的ID字符串或者dom对象
  • debug这个就不用说了,为了开发调试使用,会记录详细的上传过程,便于查找问题出现的位置
 
    除了配置之外,在说明一下uploadStoredFiles这个方法,是为了方便为手动上传绑定时候使用。
    
    至此,一个简单的无刷新上传就完成了。这里对thinkjs和Fine Uploader的讲解都是一些皮毛,简单的说明一下怎么使两者很好的配合起来,如果想要详细的学习thinkjs和Fine Uploader还是建议直接去官网学习。
 
    thinkjs官网:http://thinkjs.org/
    Fine Uploader官网:http://fineuploader.com/
 
参考资料:
 
 
 

thinkjs与Fine Uploader的邂逅的更多相关文章

  1. Fine Uploader文件上传组件

    最近在处理后台数据时需要实现文件上传.考虑到对浏览器适配上采用Fine Uploader. Fine Uploader 采用ajax方式实现对文件上传.同时在浏览器中直接支持文件拖拽[对浏览器版本有要 ...

  2. [代码示例]用Fine Uploader+ASP.NET MVC实现ajax文件上传

    原文 [代码示例]用Fine Uploader+ASP.NET MVC实现ajax文件上传 Fine Uploader(http://fineuploader.com/)是一个实现 ajax 上传文件 ...

  3. 用Fine Uploader+ASP.NET MVC实现ajax文件上传[代码示例]

    Fine Uploader(http://fineuploader.com/)是一个实现 ajax 上传文件的 Javascript 组件. This project attempts to achi ...

  4. Fine Uploader 简单配置方法

    由于jquery.uploadify是基于flash的jquery上传控件,客户老是说出问题,所以今天换成了一个纯js的异步上传控件. 这方面的资料很少,故此记下来分享一下. 项目地址:Fine Up ...

  5. web文件上传组件比较jQuery File Upload和Fine Uploader

    jQuery File Upload: https://blueimp.github.io/jQuery-File-Upload/ Fine Uploader: http://fineuploader ...

  6. [Fine Uploader] 用Fine Uploader+ASP.NET MVC实现ajax文件上传[代码示例]

    Fine Uploader(http://fineuploader.com/)是一个实现 ajax 上传文件的 Javascript 组件   This project attempts to ach ...

  7. 上传组件Fine Uploader在ASP.NET中的应用

    现如今,世面上流行着许多前端上传组件,例如:Uploadify(http://www.uploadify.com/),Fine Uploader,等等.这篇博客从头开始,介绍如何在ASP.NET MV ...

  8. Fine Uploader + Spring3.2.2(Java+html5上传) SpringMVC+jquery-fineuploader 文件上传

    需求:要实现多文件上传,且要支持手机等移动设备... springmvc文件上传真头疼,网上搜了半天没发现都是TMD的用submit按钮提交到后台的,就没有插件的吗?最后发现了fineUploader ...

  9. GitHub托管BootStrap资源汇总(持续更新中…)

    Twitter BootStrap已经火过大江南北,对于无法依赖美工的程序员来说,这一成熟前卫的前端框架简直就一神器,轻轻松松地实现出专业的UI效果.GitHub上相关的的开源项目更是层出不穷,在此整 ...

随机推荐

  1. shell输出加颜色

    shell输出加颜色 #cat a.sh #!/bin/sh blue=`tput setaf 4` reset=`tput sgr0` echo "${blue}[INFORMATION] ...

  2. jQuery 遍历 json 方法大全

    1.for循环: var obj = { "status":1, "bkmsg":"\u6210\u529f", "bkdata& ...

  3. poj 2049 Let it Bead(polya模板)

      Description Cannery Row percent of the target audience insists that the bracelets be unique. (Just ...

  4. mysql插入数据时,中文乱码

    MySQL 插入数据时,中文乱码问题的解决(转) 当向 MySQL 数据库插入一条带有中文的数据形如 insert into employee values(null,'张三','female','1 ...

  5. StroyBoard中UICollectionView中添加Header和footer

    到Storyboard中,选择collection view controller中的"Collection View".在Attributes inspector中,选择&quo ...

  6. 使用代码自定义UIView注意一二三

    文/CoderAO(简书作者)原文链接:http://www.jianshu.com/p/68b383b129f9著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 当一撮样式一样的视图在 ...

  7. windows 删除多层文件夹

    眼下目录d:\clu_1下有99个目录,名字为0,1....99,每一个目录下又有25个目录,目录名为0,1,....24,其下其下又有以日期命名的目录(如20140521),最后是zip文件.如一个 ...

  8. Oracle CheckPoint进程

    在实例经过分配内存结构,加载控制文件后,然后要打开数据库的时候,需要做到控制文件,数据文件,联机重做日志保持相互状态一致性,数据库才可以打开.当数据库发生实例不正常关闭时(比如系统掉电或者Shutdo ...

  9. 安装oracle11g未找到文件WFMLRSVCApp.ear文件

    win7_64位系统,安装oracle11gR2时,报错提示: 未找到文件...WFMLRSVCApp.ear文件 解决方法如下: 将下载的两个压缩包解压至同一目录(合并)再安装即可解决此类问题.

  10. Sqlserver in 实现 参数化查询 XML类型

    原文: http://www.cnblogs.com/tangruixin/archive/2012/04/23/2465917.html 1:如果参数是int类型: declare @a xmlse ...