最近客戶要求實現論壇貼子附件裁剪功能,沒有考慮js與ios、android容器交互解決方案,單純用js去實現它的。由於本來附件上傳用的別的插件實現的,所以是在此基礎上費了不少勁,才把jQuery-photoClip裁剪功能壘上去,但好再最后成功實現了。在實現過程中遇到了幾個問題,記下來和大家一起學習研究。
由於安全原因,是不允許js操作文件的。所以jQuery-photoClip裁剪下來的是base64字符串,把此字符串上傳后台解碼為文件,就可以了。但是如果字符串過大,用post或geth上傳就會超過瀏覽器傳輸最大量,后台就會接收失敗,那看來用普通字符串上傳行不通。接着又繼續研究,不斷查找資料,問題終於解決,js把base64字符串解碼轉成Blob對象再進行上傳,效果和文件上傳一樣,php在用台用$_FILES接收就可以了。
http://www.htmleaf.com/jQuery/Image-Effects/201510292721.html 這里有jQuery-photoClip介紹與下載
<!doctype html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="format-detection" content="telephone=no, email=no" /> <title>支持移動設備觸摸手勢的jQuery圖片裁剪插件</title> <link rel="stylesheet" type="text/css" href="css/normalize.css" /> <link rel="stylesheet" type="text/css" href="css/default.css"> <style> #clipArea { margin: 20px; height: 300px; } #file, #clipBtn { margin: 20px; } #view { margin: 0 auto; width: 200px; height: 200px; } </style> <!--[if IE]> <script src="http://libs.useso.com/js/html5shiv/3.7/html5shiv.min.js"></script> <![endif]--> </head> <body ontouchstart=""> <article class="htmleaf-container"> <div id="clipArea"></div> <input type="file" id="file"> <button id="clipBtn">截取</button> <div id="view"></div> </article> <script src="http://libs.useso.com/js/jquery/2.1.1/jquery.min.js" type="text/javascript"></script> <script>window.jQuery || document.write('<script src="js/jquery-2.1.1.min.js"><\/script>')</script> <script src="js/iscroll-zoom.js"></script> <script src="js/hammer.js"></script> <script src="js/jquery.photoClip.js"></script> <script> var one_obj = { /** * @param base64Codes * 圖片的base64編碼 */ funUploadFile: function(base64Codes){ var self = this; var formData = new FormData(); //convertBase64UrlToBlob函數是將base64編碼轉換為Blob //append函數的第一個參數是后台獲取數據的參數名,在php中用$FILES['imageName']接收, formData.append("imageName",self.convertBase64UrlToBlob(base64Codes)); //ajax 提交form $.ajax({ // 你后台的接收地址 url : 'your_url', type : "POST", data : formData, dataType:"json", processData : false, // 告訴jQuery不要去處理發送的數據 contentType : false, // 告訴jQuery不要去設置Content-Type請求頭 success:function(data){ console.log('上傳成功'); }, xhr:function(){ //在jquery函數中直接使用ajax的XMLHttpRequest對象 var xhr = new XMLHttpRequest(); xhr.upload.addEventListener("progress", function(evt){ if (evt.lengthComputable) { var percentComplete = Math.round(evt.loaded * 100 / evt.total); console.log("正在提交."+percentComplete.toString() + '%'); //在控制台打印上傳進度 } }, false); return xhr; } }); }, /** * 將以base64的圖片url數據轉換為Blob * @param urlData * 用url方式表示的base64圖片數據 */ convertBase64UrlToBlob: function(urlData){ //去掉url的頭,並轉換為byte var bytes=window.atob(urlData.split(',')[1]); //處理異常,將ascii碼小於0的轉換為大於0 var ab = new ArrayBuffer(bytes.length); var ia = new Uint8Array(ab); for (var i = 0; i < bytes.length; i++) { ia[i] = bytes.charCodeAt(i); } // 此處type注意與photoClip初始化中的outputType類型保持一致 return new Blob( [ab] , {type : 'image/jpeg'}); }, init: function() { var self = this; $("#clipArea").photoClip({ width: 200, height: 200, file: "#file", view: "#view", ok: "#clipBtn", outputType: 'jpg', loadStart: function() { console.log("照片讀取中"); }, loadComplete: function() { console.log("照片讀取完成"); }, clipFinish: function(dataURL) { console.log('裁剪完成'); self.funUploadFile(dataURL); } }); } }; one_obj.init(); </script> </body> </html>