HTML5 文件异步上传 — h5uploader.js

之前写过一篇 H5 异步文件上传的文章, 但是很多朋友看着我的这个教程还是出现很多问题,文章写的不是很好,比较早了。其实通过 H5 做异步上传已经非常简单了,通过查看文档,便可以很轻松的完成这个功能,当然,如果你不愿意查看文档自己动手的话,那么就用插件咯。h5uploader是我最近封装的 HTML5 上传插件,代码才白来行,使用的话也比较简单,支持文件大小,类型,progress 等等功能。本篇教程,将向你展示 Nodejs,Java 两种服务端的上传方法,并且附有源代码示例。

插件下载

如果你是bower的用户的话,可以直接通过以下命令:

bower install h5uploader --save

当然也可以直接从 Github Clone 此项目:

git clone https://github.com/wewoor/h5uploader.git

HTML 代码

<input type="file" id="myfile" value="" name="myfile" multiple="multiple"/>
<button id="uploader">Upload</button>

以上是一个 file 类型的 input 元素以及一个上传触发按钮,后面带有 multiple 属性,表示次处支持文件多选上传,当然,你也可以一次提交多个 input 元素,例如:

<input type="file" id="myfile" value="" name="myfile" multiple="multiple"/>
<input type="file1" id="myfile1" value="" name="myfile" multiple="multiple"/>
<button id="uploader">Upload</button>

这种方法同样是可以的,只不过服务端解析的时候要更麻烦。

Javascript

<script type="text/javascript" src="html5uploader.js"></script>
    <script type="text/javascript">
     var uploader = document.getElementById('uploader');
        uploader.addEventListener("click", function(e) {

        H5Uploader.upload({
            action: 'upload',
            id: 'myfile0',
            size: {
                max: 5000, // 5000kb
                valide: function(e) {
                    if (e) {
                        alert("The size of " + e.name + " is exceed max value!");
                    }
                }
            }, // MB
            type: {
                name: 'csv;png;jpg',
                valide: function(e) {
                    if (e) {
                        alert("The type of " + e.name + " is not supported!");
                    }
                }
            },
            progress: function() {
                    var p = document.createElement('p');
                    p.innerHTML = "uploading";
                    p.id = "loading";
                    document.body.appendChild(p);
            },
            success: function(data) {
                alert(data);
                if (data && data == 200) {
                    document.getElementById('loading').innerHTML = "The file upload successfully!";
                    alert("The file upload successfully.");
                }
            },
            fail: function(data) {

            }
        });

    }, false);
    </script>

以上是针对单个 input 元素的上传,H5Uploader.upload()方法是支持Array类型和Object类型的,也就是说,如果你有多个 input 元素同时上传的需求的话,你可以这样写:

   uploader.addEventListener("click", function(e) {

        H5Uploader.upload([{
            action: 'upload',
            id: 'myfile0',
            size: {
                max: 5000, // 5000kb
                valide: function(e) {
               }
            }, // MB
            type: {
                name: 'csv;json',
                valide: function(e) {
               }
            },
            progress: function() {
                               },
            success: function(data) {
            },
            fail: function(data) {

            }
        },{
            action: 'upload',
            id: 'myfile1',
            size: {
                max: 5000, // 5000kb
                valide: function(e) {
               }
            }, // MB
            type: {
                name: 'png;jpg',
                valide: function(e) {
               }
            },
            progress: function() {
            },
            success: function(data) {
            },
            fail: function(data) {

            }
        }]);

    }, false);

Nodejs 服务端

服务端是 expressjs,利用的一个上传中间件multer

var express = require('express');
var multer = require('multer');
var app = express();
var done = false;

app.use(express.static('./public'));

// respond with "hello world" when a GET request is made to the homepage
app.post('/upload',[multer({dest: './uploads/'}), function(req, res) {
    try {
        console.log(req.body.myfile);
        console.log(req.files);
        res.json(200);
    } catch (e) {
        console.log(e);
    }
}]);

完整的示例代码,请看

Java servlet 示例

此处没有用任何框架或者库,只是Servlet3.0, 用 tomcat6 的同学要注意哦。

package com.h5uploader.demo;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;


@MultipartConfig
public class UploaderServlet extends HttpServlet {

 public void service(HttpServletRequest req, HttpServletResponse res)
   throws IOException, ServletException {
  
  res.setContentType("text/html;charset=UTF-8");

     // Create path components to save the file
     final String path = "/Users/ziv/Desktop/";
     final Part filePart = req.getPart("myfile0");
     final String fileName = getFileName(filePart);

     OutputStream out = null;
     InputStream filecontent = null;
     final PrintWriter writer = res.getWriter();

     try {
         out = new FileOutputStream(new File(path + File.separator
                 + fileName));
         filecontent = filePart.getInputStream();

         int read = 0;
         final byte[] bytes = new byte[1024];

         while ((read = filecontent.read(bytes)) != -1) {
             out.write(bytes, 0, read);
         }
         writer.println("New file " + fileName + " created at " + path);

     } catch (FileNotFoundException fne) {
         writer.println("You either did not specify a file to upload or are "
                 + "trying to upload a file to a protected or nonexistent "
                 + "location.");
         writer.println("<br/> ERROR: " + fne.getMessage());


     } finally {
         if (out != null) {
             out.close();
         }
         if (filecontent != null) {
             filecontent.close();
         }
         if (writer != null) {
             writer.close();
         }
     }
 }

 private String getFileName(final Part part) {
     final String partHeader = part.getHeader("content-disposition");
     for (String content : part.getHeader("content-disposition").split(";")) {
         if (content.trim().startsWith("filename")) {
             return content.substring(
                     content.indexOf('=') + 1).trim().replace("\"", "");
         }
     }
     return null;
 }

}

以上的上传示例是来自官方的代码,我个人也是测试过的,完整的示例

另外我还写了一个sails的版本,有需要的可以点击查看

结语

以上则是这个插件使用的全部内容,如果有什么问题可以直接点击示例代码进行查看,另外插件是我才写出来的,如果有什么问题请告诉我。谢谢,希望它能帮助你!

作者:Ziv 小威

原文地址:http://imziv.com/blog/article/read.htm?id=62


最后修改于 2015-05-07