1、js文件,這個是封裝過的,借用了網絡上的代碼而後修改的javascript
(function(window,undefined){ var upload = function(){ this.init(); }; upload.prototype={ init:function(){ var inputDom = document.createElement("input"); inputDom.type = "file"; inputDom.setAttribute("accept","image/*"); inputDom.setAttribute("multiple","multiple"); this.inputDom = inputDom; this.bindChange(); }, start:function(o){ this.opt = this.setOpt(o); this.inputDom.value = ""; this.canvasBefore(); this.inputDom.click(); }, bindChange:function(){ var dom = this.inputDom; var that = this; dom.onchange = function() { try{ if (!this.files.length) return; var files = Array.prototype.slice.call(this.files); if (files.length > 1) { alert("最多隻可上傳1張圖片"); return; } _shade_layer.show("上傳中,請稍後..."); files.forEach(function(file, i) { if (!/\/(?:jpeg|png|gif)/i.test(file.type)) return; var reader = new FileReader(); //獲取圖片大小 var size = file.size / 1024 > 1024 ? (~~ (10 * file.size / 1024 / 1024)) / 10 + "MB": ~~ (file.size / 1024) + "KB"; reader.onload = function() { var result = this.result; var img = new Image(); img.src = result; //超出大小 if(result.length > that.opt.maxSize){ alert("圖片大小不能超過5M"); _shade_layer.hide(); return; } //若是圖片大小小於100kb,則直接上傳 if (result.length <= that.opt.minSize) { img = null; that.upload(result, file.type); return; } //圖片加載完畢以後進行壓縮,而後上傳 if (img.complete) { callback(); } else { img.onload = callback; } function callback() { var data = that.compress(img); that.upload(data, file.type); img = null; } }; reader.readAsDataURL(file); }) }catch(e){ _shade_layer.hide(); alert("上傳出現錯誤"); return ; } }; }, /** * 繪製壓縮圖片的canvas */ canvasBefore:function(){ var canvasDom = document.getElementById("canvas_id"); if(canvasDom){canvasDom.parent().remove();} var tCanvasDom = document.getElementById("tCanvas_id"); if(tCanvasDom){tCanvasDom.parent().remove();} //用於壓縮圖片的canvas var canvas = document.createElement("canvas"); canvas.id = "canvas_id"; this.canvas = canvas; this.ctx = canvas.getContext('2d'); //瓦片canvas var tCanvas = document.createElement("canvas"); tCanvas.id = "tCanvas_id"; this.tCanvas = tCanvas; this.tctx = tCanvas.getContext("2d"); }, /** * 使用canvas對大圖片進行壓縮 * @param {} img 圖片對象 * @return {} */ compress:function(img) { var canvas = this.canvas; var tCanvas = this.tCanvas; var tctx = this.tctx; var ctx = this.ctx; var initSize = img.src.length; var width = img.width; var height = img.height; //若是圖片大於四百萬像素,計算壓縮比並將大小壓至400萬如下 var ratio; if ((ratio = width * height / 4000000) > 1) { ratio = Math.sqrt(ratio); width /= ratio; height /= ratio; } else { ratio = 1; } canvas.width = width; canvas.height = height; //鋪底色 ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, canvas.width, canvas.height); //若是圖片像素大於100萬則使用瓦片繪製 var count; if ((count = width * height / 1000000) > 1) { count = ~~ (Math.sqrt(count) + 1); //計算要分紅多少塊瓦片 //計算每塊瓦片的寬和高 var nw = ~~ (width / count); var nh = ~~ (height / count); tCanvas.width = nw; tCanvas.height = nh; for (var i = 0; i < count; i++) { for (var j = 0; j < count; j++) { tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh); ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh); } } } else { ctx.drawImage(img, 0, 0, width, height); } //進行最小壓縮 var ndata = canvas.toDataURL('image/jpeg', this.opt.proportion); /* console.log('壓縮前:' + initSize); console.log('壓縮後:' + ndata.length); console.log('壓縮率:' + ~~ (100 * (initSize - ndata.length) / initSize) + "%"); */ tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0; this.canvas = canvas; this.tCanvas = tCanvas; this.tctx = tctx; this.ctx = ctx; return ndata; }, /** * 獲取blob對象的兼容性寫法 * @param buffer * @param format * @returns {*} */ getBlob:function(buffer, format) { try { return new Blob(buffer, { type: format }); } catch(e) { var bb = new(window.BlobBuilder || window.WebKitBlobBuilder || window.MSBlobBuilder); buffer.forEach(function(buf) { bb.append(buf); }); return bb.getBlob(format); } }, /** * 獲取formdata * @return {} */ getFormData:function() { var isNeedShim = ~navigator.userAgent.indexOf('Android') && ~navigator.vendor.indexOf('Google') && !~navigator.userAgent.indexOf('Chrome') && navigator.userAgent.match(/AppleWebKit\/(\d+)/).pop() <= 534; return isNeedShim ? new this.FormDataShim() : new FormData(); }, /** * formdata 補丁, 給不支持formdata上傳blob的android機打補丁 */ FormDataShim:function() { var o = this, parts = [], boundary = Array(21).join('-') + ( + new Date() * (1e16 * Math.random())).toString(36), oldSend = XMLHttpRequest.prototype.send; this.append = function(name, value, filename) { parts.push('--' + boundary + '\r\nContent-Disposition: form-data; name="' + name + '"'); if (value instanceof Blob) { parts.push('; filename="' + (filename || 'blob') + '"\r\nContent-Type: ' + value.type + '\r\n\r\n'); parts.push(value); } else { parts.push('\r\n\r\n' + value); } parts.push('\r\n'); }; // Override XHR send() XMLHttpRequest.prototype.send = function(val) { var fr, data, oXHR = this; if (val === o) { // Append the final boundary string parts.push('--' + boundary + '--\r\n'); // Create the blob data = getBlob(parts); // Set up and read the blob into an array to be sent fr = new FileReader(); fr.onload = function() { oldSend.call(oXHR, fr.result); }; fr.onerror = function(err) { throw err; }; fr.readAsArrayBuffer(data); // Set the multipart content type and boudary this.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary); XMLHttpRequest.prototype.send = oldSend; } else { oldSend.call(this, val); } }; }, /** * 圖片上傳,將base64的圖片轉成二進制對象,塞進formdata上傳 * @param {} basestr * @param {} type * @param {} $li */ upload:function(basestr, type) { var that = this; var text = window.atob(basestr.split(",")[1]); var buffer = new Uint8Array(text.length); var pecent = 0, loop = null; for (var i = 0; i < text.length; i++) { buffer[i] = text.charCodeAt(i); } var blob = this.getBlob([buffer], type); var xhr = new XMLHttpRequest(); var formdata = this.getFormData(); formdata.append('imagefile', blob); xhr.open('post', this.opt.uploadURL); xhr.onreadystatechange = function() { this.canvas = null; this.tCanvas = null; this.tctx = null; this.ctx = null; var func = that.opt.callBackFunc; var id = that.opt.id; var oDataObj = that.opt.oDataObj; var nType = that.opt.nType; var frameCallBackFunc = that.opt.frameCallBackFunc; var strCallbackFunc = that.opt.strCallbackFunc; oDataObj["strCallbackFunc"] = strCallbackFunc; oDataObj["nType"] = nType; if (xhr.readyState == 4 && xhr.status == 200) { var url = xhr.responseText || ""; console.log(url); var nState = url.length == 0 ? -1 : 0; var strMsg = url.length == 0 ? "上傳失敗" : url; oDataObj["nState"] = nState; oDataObj["strMsg"] = strMsg; oDataObj = JSON.stringify(oDataObj); eval(frameCallBackFunc+"('"+oDataObj+"')"); _shade_layer.hide(); } if(xhr.status != 200){ oDataObj["nState"] = -1; oDataObj["strMsg"] = "上傳失敗"; oDataObj = JSON.stringify(oDataObj); eval(frameCallBackFunc+"('"+oDataObj+"')"); _shade_layer.hide(); } }; xhr.send(formdata); },setOpt:function(o){ var defaultOptions={ nType:'', //回調的不一樣類型,經過這個類型來改_plus.callbackuploadPicture裏面對於回調的具體方法,其實主要就是控制最終回調函數的參數 minSize:100 * 1024, //最小爲100kb,也就是說100kb如下的不壓縮直接上傳 maxSize:1024 * 1024 * 5, //最大爲10M,也就是說100kb如下的不壓縮直接上傳 proportion:0.3, //壓縮比例:從0-1之間 strCallbackFunc:'', frameCallBackFunc:'', oDataObj:{}, uploadURL:'http://pocketwap.xxx.com/Servlet/fileUpload.svl' }; if(o && Object.prototype.toString.call(o)=='[object Object]') { for(var k in o) { defaultOptions[k]= typeof o[k]==='undefined' ? defaultOptions[k] : o[k]; } } return defaultOptions; } } window.upload=upload; })(window,undefined) var _upload = new upload();
2、js頁面使用以下:java
_upload.start({ id:Id, callBackFunc:strCallbackFunc //回調地址 });
3、服務端接收,這邊由於是要統一上傳到文件服務器,因此這裏中轉了一下,若是不須要中轉,直接就能夠在這裏面處理就行android
package com.xxx.businesscenter.web; import java.io.BufferedInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.log4j.Logger; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.cdoframework.cdolib.base.UUidGenerator; /** * Servlet implementation class FileUploadServlet */ public class FileUploadServlet extends HttpServlet { private static final long serialVersionUID = 1L; private Logger log=Logger.getLogger(ApplicationListener.class); /** * @see HttpServlet#HttpServlet() */ public FileUploadServlet() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub this.doPost(request, response); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub String strResult = ""; DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); try { List<FileItem> items = upload.parseRequest(request); if(items.size() > 0 ){ FileItem item = items.get(0); if(!item.isFormField()){ strResult = uploadFile(item); } } } catch (FileUploadException e) { log.info(e); } response.getWriter().print(strResult); } private String uploadFile(FileItem item) { String contentType = item.getContentType(); String postfix = contentType.split("/")[1]; String result = ""; String end = "\r\n"; String twoHyphens = "--"; String boundary = "*****"; String newName = UUidGenerator.genenator() + "."+postfix; String actionUrl = "http://file.xxx.com.cn/Servlet/fileUpload.svl"; BufferedInputStream bufin = null; InputStream is = null; try { URL url = new URL(actionUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(10000); //超時時間爲10秒 conn.setDoInput(true); conn.setDoOutput(true); conn.setUseCaches(false); conn.setRequestMethod("POST"); conn.setRequestProperty("Connection", "Keep-Alive"); conn.setRequestProperty("Charset", "UTF-8"); conn.setRequestProperty("Content-Type","multipart/form-data;boundary=" + boundary); DataOutputStream ds = new DataOutputStream(conn.getOutputStream()); ds.writeBytes(twoHyphens + boundary + end); ds.writeBytes("Content-Disposition: form-data; " + "name=\"file1\";filename=\"" + newName + "\"" + end); ds.writeBytes("Content-Type:" + contentType + "\r\n\r\n"); bufin = new BufferedInputStream(item.getInputStream()); int bufferSize = 2048; byte[] buffer = new byte[bufferSize]; int length = -1; while ((length = bufin.read(buffer)) != -1) { ds.write(buffer, 0, length); } ds.writeBytes(end); ds.writeBytes(twoHyphens + boundary + twoHyphens + end); bufin.close(); ds.flush(); //獲取上傳返回結果 int code = conn.getResponseCode(); is = conn.getInputStream(); int ch; StringBuffer b = new StringBuffer(); while ((ch = is.read()) != -1) { b.append((char) ch); } String str = b.toString(); log.info("-------------------------"+str); if (conn.getResponseCode() == 200) { if(str.length() > 0 ){ JSONObject jObject = JSON.parseObject(str); String strFilePath = (String) jObject.get("strFilePath"); String strFileName = (String) jObject.get("strFileName"); result = strFilePath+strFileName; log.info("-------------------------圖片上傳地址="+result); } }else{ log.info("-------------------------上傳失敗code="+code); } } catch (Exception e) { log.info(e); return result; }finally{ try { if(bufin!=null){ bufin.close(); } if(is!=null){ is.close(); } } catch (IOException e) { log.info("-------------------------流關閉失敗-------------------------"); e.printStackTrace(); } } return result; } }