html5-upload-images – 前端实现
html5+jquery 图片上传功能实现: 项目需要,开发一个手机端上传图片功能;经过百度学习,最终选择使用html5的input标签、FormData和FileReader来实现图片的上传和预览功能。
目前Android、IOS自带的浏览器均支持html5。html5 提供了input标签,将input标签的type属性设置为file,accept属性设置为image/*(接收所有的图片格式的文件)。
1
| <input id="file" type="file" accept="image/*" />
|
通过html5的 this.files[] 数组去获取上传的文件对象,FormData对象通过append方法加载文件;通过jquery的Ajax进行post的提交文件,需要将 processData、contentType 设置为false,即告诉ajax对文件formData不进行处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <script> var oFile = this.files[0]; var formData = new FormData(document.getElementById("upload_form")); formData.append("oFile", oFile); $.ajax({ url : "url", type : "post", data : formData, processData : false, contentType : false, success : function(data) { }, error : function(data) { }); </script>
|
图片的预览,通过 FileReader的readAsDataURL 方法可以将读取到的文件编码成Data URL。Data URL是一项特殊的技术,可以将资料(例如图片)内嵌在网页之中,不用放到外部文件。使用Data URL的好处是,您不需要额外再发出一个HTTP 请求到服务器端取得额外的资料;而缺点便是,网页的大小可能会变大。它适合应用在内嵌小图片,不建议将大图像文件编码成Data URL来使用。您的图像文件不能够超过浏览器限定的大小,否则无法读取图像文件。
1 2 3 4 5 6 7 8 9 10
| <script type="text/javascript"> var img = document.createElement("img"); var reader = new FileReader(); reader.onload = function(e) { img.src = this.result; }; reader.readAsDataURL(oFile); img.width = 200; div.append(img); </script>
|
完整的前端代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| <!DOCTYPE HTML PUBLIC "-//W3C//Ddiv XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/Ddiv/xhtml1-transitional.ddiv"> <html xml:lang="zh-CN" xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN"> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width" /> <link rel="stylesheet" href="http://apps.bdimg.com/libs/jquerymobile/1.4.5/jquery.mobile-1.4.5.min.css"> <script src="http://apps.bdimg.com/libs/jquery/1.10.2/jquery.min.js"></script> <script src="http://apps.bdimg.com/libs/jquerymobile/1.4.5/jquery.mobile-1.4.5.min.js"></script> <title>上传图片</title> </head> <body> <div id="upload-container"> <input id="file" type="file" accept="image/*" /> <div id="space"></div> </div> <div id="upload_form"></div> <script> $("#file").change( function() { div = $("#space"); div.empty(); var oFile = this.files[0]; var formData = new FormData(document .getElementById("upload_form")); formData.append("oFile", oFile); div.css("text-align","center");
var img = document.createElement("img"); var reader = new FileReader(); reader.onload = function(e) { img.src = this.result; }; reader.readAsDataURL(oFile); img.width = 200; div.append(img); $("#upload-container").append(div); br = document.createElement('br'); span = document.createElement('span'); span.style.color = "Red";
$.ajax({ url : "/visitor/upload/dealUpload", type : "post", data : formData, processData : false, contentType : false, success : function(data) { span.innerHTML = "图片上传成功!"; div.append(br); div.append(span); }, error : function(data) { span.innerHTML = "Error!图片上传失败!"; div.append(br); div.append(span); } }); }); </script> </body> </html>
|
下篇将讲述后端如何处理post的文件数据,简单的通过 HttpServletRequest的getRequest() 的方法无法获取该文件参数;需要 org.apache.commons.fileupload 中的 new ServletFileUpload(new DiskFileItemFactory()).parseRequest(getRequest()) 的方法去获取文件参数列表,具体详见html5+jquery图片上传功能实现–后端实现。
html5-upload-images 后端实现
项目需要,开发一个手机端上传图片功能;后端基于jfinal框架,进行图片上传的处理:1、获取文件数据;2、创建文件;3、将数据写入本地文件。
#在html5+jquery 图片上传功能实现–前端实现中,实现了ajax post提交文件的前端代码。
使用普通的 getPara() 的方法无法获取file数据
在jfinal中一般通过 getPara() 或者 getParaMap()的方法去获取post过来数据值。经过调试发现参数列表为空,即此方法无法获取post过来的file类型的数据。
使用 org.apache.commons.fileupload 来进行file数据解析
对文件上传功能,在浏览器端提供了较好的支持,只要将FORM表单的enctype属性设置为 “multipart/form-data” 即可;但在Web服务器端如何获取浏览器上传的文件,需要进行复杂的编程处理。org.apache.commons.fileupload的FileUpload 可以帮助我们解析这样的请求,将每一个项目封装成一个实现了 FileItem 接口的对象,并以列表的形式返回。
1 2
| List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(getRequest());
|
获取文件信息
通过 ServletFileUpload 静态类来解析Request,工厂类 FileItemFactory 会对mulipart类的表单中的所有字段进行处理,不只是file字段。getName() 得到文件名,getString() 得到表单数据内容,isFormField() 可判断是否为普通的表单项。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| for (FileItem item : items) { if (item.isFormField()) { ajaxUploadResult += "Field " + item.getFieldName() + " with value: " + item.getString() + " is successfully read\n\r"; log.info(ajaxUploadResult); } else { InputStream inputStream = item.getInputStream(); String filePath = createFilePath(); String fileName = createFileName(); String imagePath = uploadFile(inputStream, fileName, filePath); File file = new File(imagePath); }
}
|
图片上传的具体代码实现
具体uploadFile方法的实现,从inputStream每次最多读取1024byte的数据,直至将byte数据全部写入 FileOutputStream 对象的文件中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| * 上传图片 * * @author esonzys modify_date 2015年12月22日 * @param fileData * 图片base64编码的数据 * @param fileName * 生成的文件名 * @param uploadPath * 上传图片的路径 * @return */ @SuppressWarnings({ "restriction" }) private String uploadFile(InputStream fileData, String fileName, String uploadPath) { File file = new File(uploadPath); if (!file.exists()) { file.mkdirs(); } String imagePath = uploadPath + File.separator + fileName + ".jpg";
file = new File(imagePath); try { FileOutputStream outputStream = new FileOutputStream(file); int bytesRead = -1; byte[] buffer = new byte[1024]; while ((bytesRead = fileData.read(buffer)) > 0) { outputStream.write(buffer, 0, bytesRead); outputStream.flush(); }
outputStream.close(); } catch (IOException e) { log.error(e.getMessage()); e.printStackTrace(); }
return imagePath; }
|
至此,就可以在服务器相应的filePath路径中找到上传的图片文件了。