上传文件(FineUploader)插件

本文详细介绍FineUploader的使用方法,包括JavaScript配置、UI模板定制、Java后台处理等,并附带示例代码与效果截图。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

插件下载地址:http://pan.baidu.com/s/1mhqRCyk(表示虽然有官网,但是官网的貌似不对)

Fine Uploader特点如下
Fine Uploader Features: 
A:支持文件上传进度显示. 
B:文件拖拽浏览器上传方式 
C:Ajax页面无刷新. 
D:多文件上传. 
F:跨浏览器. 
E:跨后台服务器端语言. 

qq.FineUploader对象还有如下控制参数:

validation:该参数一般用来在执行上传文件操作前.在客户端做一些验证.验证操作包含文件格式.文件大小.等添加格式如下:

   1:   validation: 
   2:    {
   3:          allowedExtensions: ['jpeg', 'jpg', 'gif', 'png'],
   4:          sizeLimit: 204800 // 200 kB = 200 * 1024 bytes
   5:    }

allowedExtensions控制上传文件的后缀格式数组.

sizeLimit上传文件大小的上限,单位为byte的数值.浏览器不一定支持本设置.也可以在服务器端里设置.

minSizeLimit:上传文件大小的下限,单位为byte的数值.同上有些浏览器存在适配问题.建议统一在服务端设置.

另外针对qq.FineUploder对象在执行上传操作整个过程.定义了五个客户端可控做额外操作的事件.可以再callback参数下设置定义:

   1:  callbacks: 
   2:  {
   3:          onSubmit: function(id, fileName) {
   4:            $messages.append('<div id="file-' + id + '" class="alert" style="margin: 20px 0 0"></div>');
   5:          },
   6:          onUpload: function(id, fileName) {
   7:            $('#file-' + id).addClass('alert-info')
   8:                            .html('<img src="client/loading.gif" alt="Initializing. Please hold."> ' +
   9:                            'Initializing ' +
  10:                            '“' + fileName + '”');
  11:          }
  12:  }

onSubmit事件:文件开始提交.调用参数格式如下:onSubmit:  function(id,  fileName)  {}.

onUpload事件: 文件开始上传.调用参数格式如下:onUpload: function(id, fileName) {}.

onProgress事件: 文件正在上传.调用参数格式如下:onProgress:  function(id,  fileName,  loaded,  total)  {}.

onComplete事件: 文件上传成功. 调用参数格式如下:onComplete:  function(id,  fileName,  responseJSON)  {}.

onCancel事件: 取消文件上传.调用参数格式如下:onCancel:  function(id,  fileName)  {}.

如上五个事件基本覆盖整个上传文件操作中所有过程.完全以开放的形式可以再客户端操作.关于调用如上事件参数说明如下:

Id:表示第几个开始上传的文件.Fine Uploder定义是默认从0开始计数.

fileName:上传文件的文件名.

loaded:表示已经上传到服务器端数据的大小[byte].

total: 需要上传文件的大小.

responseJSON: 用来在上传操作完成后返回的Json格式的数据.通过Jquery反序列化出来对象.其中包含一个IsSuccess属性用来判断此次上传是否成功.

如果你想在上传过程向服务器端传递数据.可以通过如下参数控制:

params:用来向服务器端传递数据.注意params采用key-value的数组存储.采用Post方式发送给服务器端.一般传递参数格式如下:

   1:    params: 
   2:    {                
   3:        argument1: "value1",                
   4:        argument2: "value2"                
   5:    },

ok.这时基本关于Fine Uploader客户端初始化和控制操作选项基本完成.当我们需要上传操作时.如果IsAuto=false时可以通过已经定义qq.FineUploader对象的uploadStoreFiles()方式手工触发上传操作:

   1:  $('#triggerUpload').click(function() {
   2:          uploader2.uploadStoredFiles();
   3:      });
如果我们此时点击上传会发现.则提示上传失败. 因为还没有对上传服务器端做任何处理:
   1:    request: 
   2:      {
   3:          endpoint: 'server/handlerfunction'
   4:      },

这时我们需要在EndPoint指定处理文件上传的Php文件[这里是phpdemo]


index.html

[html] view plain copy
  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4.     <title>上传文件测试</title>  
  5.     <link href="fine-uploader/fineuploader-new.css" rel="stylesheet">  
  6. <!--     <link href="fine-uploader/bootstrap.min.css" rel="stylesheet"> -->  
  7.     <script src="fine-uploader/fine-uploader.min.js"></script>  
  8.     <script type="text/template" id="qq-template">  
  9.         <div class="qq-uploader-selector qq-uploader" qq-drop-area-text="Drop files here">  
  10.             <div class="qq-total-progress-bar-container-selector qq-total-progress-bar-container">  
  11.                 <div role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" class="qq-total-progress-bar-selector qq-progress-bar qq-total-progress-bar"></div>  
  12.             </div>  
  13.             <div class="qq-upload-drop-area-selector qq-upload-drop-area" qq-hide-dropzone>  
  14.                 <span class="qq-upload-drop-area-text-selector"></span>  
  15.             </div>  
  16.             <div class="qq-upload-button-selector qq-upload-button">  
  17.                 <div>Upload a file</div>  
  18.             </div>  
  19.             <span class="qq-drop-processing-selector qq-drop-processing">  
  20.                 <span>Processing dropped files...</span>  
  21.                 <span class="qq-drop-processing-spinner-selector qq-drop-processing-spinner"></span>  
  22.             </span>  
  23.             <ul class="qq-upload-list-selector qq-upload-list" aria-live="polite" aria-relevant="additions removals">  
  24.                 <li>  
  25.                     <div class="qq-progress-bar-container-selector">  
  26.                         <div role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" class="qq-progress-bar-selector qq-progress-bar"></div>  
  27.                     </div>  
  28.                     <span class="qq-upload-spinner-selector qq-upload-spinner"></span>  
  29.                     <img class="qq-thumbnail-selector" qq-max-size="100" qq-server-scale>  
  30.                     <span class="qq-upload-file-selector qq-upload-file"></span>  
  31.                     <span class="qq-edit-filename-icon-selector qq-edit-filename-icon" aria-label="Edit filename"></span>  
  32.                     <input class="qq-edit-filename-selector qq-edit-filename" tabindex="0" type="text">  
  33.                     <span class="qq-upload-size-selector qq-upload-size"></span>  
  34.                     <button type="button" class="qq-btn qq-upload-cancel-selector qq-upload-cancel">Cancel</button>  
  35.                     <button type="button" class="qq-btn qq-upload-retry-selector qq-upload-retry">Retry</button>  
  36.                     <button type="button" class="qq-btn qq-upload-delete-selector qq-upload-delete">Delete</button>  
  37.                     <span role="status" class="qq-upload-status-text-selector qq-upload-status-text"></span>  
  38.                 </li>  
  39.             </ul>  
  40.   
  41.             <dialog class="qq-alert-dialog-selector">  
  42.                 <div class="qq-dialog-message-selector"></div>  
  43.                 <div class="qq-dialog-buttons">  
  44.                     <button type="button" class="qq-cancel-button-selector">Close</button>  
  45.                 </div>  
  46.             </dialog>  
  47.   
  48.             <dialog class="qq-confirm-dialog-selector">  
  49.                 <div class="qq-dialog-message-selector"></div>  
  50.                 <div class="qq-dialog-buttons">  
  51.                     <button type="button" class="qq-cancel-button-selector">No</button>  
  52.                     <button type="button" class="qq-ok-button-selector">Yes</button>  
  53.                 </div>  
  54.             </dialog>  
  55.   
  56.             <dialog class="qq-prompt-dialog-selector">  
  57.                 <div class="qq-dialog-message-selector"></div>  
  58.                 <input type="text">  
  59.                 <div class="qq-dialog-buttons">  
  60.                     <button type="button" class="qq-cancel-button-selector">Cancel</button>  
  61.                     <button type="button" class="qq-ok-button-selector">Ok</button>  
  62.                 </div>  
  63.             </dialog>  
  64.         </div>  
  65.     </script>  
  66. </head>  
  67. <body>  
  68.     <div id="fine-uploader"></div>  
  69.     <script>  
  70.         var uploader = new qq.FineUploader({  
  71.             debug: true,  
  72.             element: document.getElementById('fine-uploader'),  
  73.             request: {  
  74.                 endpoint: 'uploadhandler.php'  
  75.             },  
  76.             deleteFile: {  
  77.                 enabled: true,  
  78.                 endpoint: ''  
  79.             },  
  80.             retry: {  
  81.                enableAuto: true  
  82.             },  
  83.             callbacks:{  
  84.                 onComplete:  function(id,  fileName,  responseJSON)  {  
  85.                     console.log(responseJSON);  
  86.                 }  
  87.             }  
  88.         });  
  89.     </script>  
  90. </body>  
  91. </html>  



===================================================================================

近来做一个需要有附件管理的公告版,于是发现了这个FineUploader,纯Javascript实现,Ajax方式,上传文件不刷新页面,不依赖于任何第三方库,非常好用。但刚开始使用时google了很多资料,包括官方的文档和demo。发现网上的很多资料要么很老,要么对我参考意义不大。至这个功能完成,写下自己的心得,给自己留点记录,如果能对别人有点参考价值则更佳。

FineUploader官方网站:http://fineuploader.com/ ,打包好的js是要收费的,价格还不便宜。

开源的项目:https://github.com/FineUploader/fine-uploader

本文中用到的FineUploader已上传到http://download.youkuaiyun.com/detail/jxiaoliu/8071341(已精简,去掉了所有用不到的文件,包括模板)

一、FineUploader所需的代码

首先,引入必须的js文件和css

[javascript] view plain copy
  1. <link href="<%=request.getContextPath()%>/fineuploader5/fineuploader-5.0.2.css" rel="stylesheet"/>  
  2. <script src="<%=request.getContextPath()%>/fineuploader5/fineuploader-5.0.2.js" type="text/javascript"></script>  
OK,就这两个文件就可以了。

接下来,就可以在js中实例化这个uploader:

[javascript] view plain copy
  1. var submitFile = false;//用于控制仅在”提交“按钮按下时提交文件  
  2. var uploader = null;  
  3. function createUploader() {  
  4.     uploader = new qq.FineUploader({  
  5.         element: document.getElementById('fine-uploader'),  
  6.         autoUpload: false,  
  7.             request: {  
  8.                 endpoint: '<%=request.getContextPath()%>/updownfile/UploadFile?op=add'  
  9.             },  
  10.             session: {  
  11.                 endpoint: '<%=request.getContextPath()%>/manage/Bulletin?op=getattach',  
  12.                 params: {'id': ${bulletin.id}}  
  13.             },  
  14.             deleteFile: {  
  15.                 enabled: true,  
  16.                 endpoint: '<%=request.getContextPath()%>/manage/Bulletin?op=del',  
  17.                 method: 'POST',  
  18.                 forceConfirm: true,  
  19.                 confirmMessage: '确定要删除文件 {filename} 吗? 不可恢复!!',  
  20.                 deletingFailedText: '删除失败!'  
  21.             },  
  22.             editFilename: {  
  23.                    enabled: false  
  24.             },  
  25.             callbacks: {  
  26.                 onAllComplete:  function(successIDs, failIDs)  {  
  27.                     if(submitFile)  
  28.                         submitdata(successIDs);  
  29.                 }  
  30.             }  
  31.     });  
  32. }  
必须在页面初始化时进行此操作,继续加入下面这句:
[javascript] view plain copy
  1. window.onload = createUploader;  
FineUploader必须实例化到html页面中的某个“容器”内,一般为<div>元素,第一个选项“element”即指出对应的html元素。所以在页面中必须有如下元素存在:
[html] view plain copy
  1. <div id="fine-uploader"></div>  
此外,由于FineUploader分为core和UI两个类别,其中core应该是用户完全定制到自己的JS程序中去的,需要写自己的用户界面。对于初学者或一般用户来说,可以直接使用FineUploader提供的模板(template,用户可以去开源项目中下载),这里是直接拷贝模板文件(default.html)中相应的代码段到当前html页面的任意位置:
[html] view plain copy
  1. <script type="text/template" id="qq-template">  
  2.   <div class="qq-uploader-selector qq-uploader">  
  3.     <div class="qq-upload-button-selector qq-upload-button">  
  4.       <div>上传附件</div>  
  5.     </div>  
  6.     <ul class="qq-upload-list-selector qq-upload-list">  
  7.       <li>  
  8.         <div class="qq-progress-bar-container-selector">  
  9.           <div class="qq-progress-bar-selector qq-progress-bar"></div>  
  10.         </div>  
  11.         <span class="qq-upload-spinner-selector qq-upload-spinner"></span>  
  12.         <span class="qq-edit-filename-icon-selector qq-edit-filename-icon"></span>  
  13.         <span class="qq-upload-file-selector qq-upload-file"></span>  
  14.         <span class="qq-upload-size-selector qq-upload-size"></span>  
  15.         <a class="qq-upload-cancel-selector qq-upload-cancel" href="#">放弃上传</a>  
  16.         <a class="qq-upload-retry-selector qq-upload-retry" href="#">Retry</a>  
  17.         <a class="qq-upload-delete-selector qq-upload-delete" href="#">删除</a>  
  18.         <span class="qq-upload-status-text-selector qq-upload-status-text"></span>  
  19.       </li>  
  20.     </ul>  
  21.   </div>  
  22. </script>  
很多文档或资料说最外层的<script>标记可以不要,但本人测试不可以,必须要。其中的id属性 id=" qq-template"至关重要,否则FineUploader不知道何处去查找自己的UI界面并展示。

该模板的样式可以通过fineuploader-5.0.2.css文件进行所需的修改,这里不再赘述。

至此,FineUploader已完整,当然要运行必须要后台代码的上传支持。

二、后台Java代码

借助于apache.commons.fileupload组件进行文件的上传,代码如下:

[java] view plain copy
  1. try {  
  2.     MultipartUploadParser UploadParser = new MultipartUploadParser(request, new File(System.getProperty("java.io.tmpdir")));  
  3.     FileItem uploadfile = UploadParser.getFirstFile();  
  4.     Path file = java.nio.file.Paths.get(uploadfile.getName());  
  5.     uploadfile.write(new File(rootpath + "/temp/" + file.getFileName().toString()));  
  6.     result.put("success"true);  
  7. catch (Exception e) {  
  8.     result.put("success"false);  
  9.     response.getWriter().print(result.toString());  
  10.     e.printStackTrace();  
  11. }  

必须注意的是,文件上传成功后,必须返回前台一个JSON格式的对象,其中必须含有一个"success"对象,其值为true或者false,代表着文件上传的成功或失败。

另外,当用户选择多个文件并上传时,是以多线程的方式各自独立同时进行的。每一个文件上传成功都会触发callbacks中的onComplete事件,所有文件上传成功后触发onAllComplete事件。

其中的MultipartUploadParser类对象定义如下:

[java] view plain copy
  1. package updownfile;  
  2.   
  3. import org.apache.commons.fileupload.FileItem;  
  4. import org.apache.commons.fileupload.FileUploadException;  
  5. import org.apache.commons.fileupload.disk.DiskFileItemFactory;  
  6. import org.apache.commons.fileupload.servlet.ServletFileUpload;  
  7. import org.apache.commons.lang3.StringUtils;  
  8. import org.slf4j.Logger;  
  9. import org.slf4j.LoggerFactory;  
  10.   
  11. import javax.servlet.http.HttpServletRequest;  
  12.   
  13. import java.io.File;  
  14. import java.io.IOException;  
  15. import java.io.UnsupportedEncodingException;  
  16. import java.util.*;  
  17.   
  18. public class MultipartUploadParser  
  19. {  
  20.     final Logger log = LoggerFactory.getLogger(MultipartUploadParser.class);  
  21.   
  22.     private Map params = new HashMap();  
  23.   
  24.     private List files = new ArrayList();  
  25.   
  26.     // fileItemsFactory is a field (even though it's scoped to the constructor) to prevent the  
  27.     // org.apache.commons.fileupload.servlet.FileCleanerCleanup thread from attempting to delete the  
  28.     // temp file before while it is still being used.  
  29.     //  
  30.     // FileCleanerCleanup uses a java.lang.ref.ReferenceQueue to delete the temp file when the FileItemsFactory marker object is GCed  
  31.     private DiskFileItemFactory fileItemsFactory;  
  32.   
  33.     @SuppressWarnings("unchecked")  
  34.     public MultipartUploadParser(HttpServletRequest request, File repository) throws Exception  
  35.     {  
  36.         if (!repository.exists() && !repository.mkdirs())  
  37.         {  
  38.             throw new IOException("Unable to mkdirs to " + repository.getAbsolutePath());  
  39.         }  
  40.   
  41.         fileItemsFactory = setupFileItemFactory(repository);  
  42.   
  43.         ServletFileUpload upload = new ServletFileUpload(fileItemsFactory);  
  44.         List formFileItems = upload.parseRequest(request);  
  45.   
  46.         parseFormFields(formFileItems);  
  47.   
  48.         if (files.isEmpty())  
  49.         {  
  50.             log.warn("No files were found when processing the requst. Debugging info follows.");  
  51.   
  52.             writeDebugInfo(request);  
  53.   
  54.             throw new FileUploadException("No files were found when processing the requst.");  
  55.         }  
  56.         else  
  57.         {  
  58.             if (log.isDebugEnabled())  
  59.             {  
  60.                 writeDebugInfo(request);  
  61.             }  
  62.         }  
  63.     }  
  64.   
  65.     private DiskFileItemFactory setupFileItemFactory(File repository)  
  66.     {  
  67.         DiskFileItemFactory factory = new DiskFileItemFactory();  
  68.         factory.setSizeThreshold(10*1024*1024);  
  69.         factory.setRepository(repository);  
  70.   
  71.     //  FileCleaningTracker pTracker = FileCleanerCleanup.getFileCleaningTracker(context);  
  72.     //  factory.setFileCleaningTracker(pTracker);  
  73.   
  74.         return factory;  
  75.     }  
  76.   
  77.     private void writeDebugInfo(HttpServletRequest request)  
  78.     {  
  79.         log.debug("-- POST HEADERS --");  
  80.         for (String header : Collections.list(request.getHeaderNames()))  
  81.         {  
  82.             log.debug("{}: {}", header, request.getHeader(header));  
  83.         }  
  84.   
  85.         log.debug("-- POST PARAMS --");  
  86.         for (String key : params.keySet())  
  87.         {  
  88.             log.debug("{}: {}", key, params.get(key));  
  89.         }  
  90.     }  
  91.   
  92.     private void parseFormFields(List items) throws UnsupportedEncodingException  
  93.     {  
  94.         for (FileItem item : items)  
  95.         {  
  96.             if (item.isFormField())  
  97.             {  
  98.                 String key = item.getFieldName();  
  99.                 String value = item.getString("UTF-8");  
  100.                 if (StringUtils.isNotBlank(key))  
  101.                 {  
  102.                     params.put(key, StringUtils.defaultString(value));  
  103.                 }  
  104.             }  
  105.             else  
  106.             {  
  107.                 files.add(item);  
  108.             }  
  109.         }  
  110.     }  
  111.   
  112.     public Map getParams()  
  113.     {  
  114.         return params;  
  115.     }  
  116.   
  117.     public List getFiles()  
  118.     {  
  119.         if (files.isEmpty())  
  120.         {  
  121.             throw new RuntimeException("No FileItems exist.");  
  122.         }  
  123.   
  124.         return files;  
  125.     }  
  126.   
  127.     public FileItem getFirstFile()  
  128.     {  
  129.         if (files.isEmpty())  
  130.         {  
  131.             throw new RuntimeException("No FileItems exist.");  
  132.         }  
  133.   
  134.         return files.iterator().next();  
  135.     }  
  136. }  

三、代码中各选项含义

下面稍微详细的介绍组件用到的几个选项,方便各位根据自己项目的需要进行更改。
  • autoUpload选项:控制用户选择文件后是否立即自动上传选中的文件,默认为true,即选中后自动上传到服务器,上传完毕后,会依次显示文件名、文件大小及一个“删除”链接(删除上传文件的解释见deleteFile选项)。这里设置值为false,表示用户选择文件后仅列出文件(此时文件名右侧会出现“放弃”链接,点此链接会去除对应的文件),在需要时手动通过uploadStoredFiles()方法进行上传。
  • multiple选项:默认为true,用户可以一次选择多个文件并上传。
  • request选项:后台接受文件上传的URL路径。设置其中的endpoint属性。
  • editFilename选项:设置是否可修改上传的文件名(本人测试时好像没发现有什么作用~~)
  • callbacks选项:回调函数,可以监听各种事件。具体的可参见官方文档。
  • deleteFile选项:用于删除已上传的文件。可以删除的文件必须是在同一个页面中已经成功上传,或者由session选项初始化的文件列表。其重要的子选项解释如下:
         endpoint:后台用于删除文件的URL地址。返回值和上传时一样必须含有“success”属性
         method:重要,必须设置为'post'
         forceConfirm:是否出现删除确认的对话框,默认值为false
  • session选项:该选项确定控件初始化时需要初始化的文件列表。若不设置该项,则初始化控件时其文件列表为空。若需要给出用户以前已经上传的文件列表,则必须设置其子选项endpoint的值以从后台返回文件列表。后台返回的值必须是一个JSON格式的数组,每个数组的对象是JSON格式的对象,必须包含“name”和“uuid”两个属性,以分别指定文件名和文件的唯一代号。具体可参看官方文档。
需要注意的是,如果之前定义了onAllComplete事件,则初始化文件列表时,每一个文件都会触发onAllComplete事件,这是因为初始化好的每个文件状态都是qq.status.UPLOAD_SUCCESSFUL,即标志为已上传成功。所以本文开头定义了一个submitFile变量并设置其初始值为false,用于判断是用户手动提交上传文件还是页面初始化,如无此判断,onAllComplete事件中的代码会重复执行。

四、几张简单的样图

1. 文件已选择,待上传:


2. 文件上传过程:

3. 文件上传成功:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值