關於H5裁剪圖片後,直傳阿里雲的一些問題 TypeArray、ArrayBuffer、Blob、File、DataURL、canvas的相互轉換 阿里OSS ajax方式 web直傳

  這段時間在工做中碰到一個須要在h5裁剪圖像,而後直傳阿里雲的需求。圖中遇到了一些小問題,分享出來你們都看看。javascript

 h5裁剪圖像:cropper.js是一個神器啊關於用法,網上能夠收羅出大量的帖子,這裏我就很少說了,大體原理就是利用canvas裁剪圖像而後生成base64的圖像(canvas.toDataURL('image/jpeg'))。html

 轉換Blob對象:接下來就是重點了,上傳圖片咱們比較傳統的作法就是將 canvas.toDataURL('image/jpeg')  傳到後臺,而後後臺再生成圖片傳到阿里雲。java

                   這樣就顯得比較繁瑣了,怎麼將 canvas.toDataURL('image/jpeg')直接傳到阿里雲?這就懵逼了。這裏不得不提到js的另外一個東西,Blob對象。android

                   file對象你們都不陌生了,那這個blob又是個什麼鬼呢?而實際上 file 對象只是 blob 對象的一個更具體的版本,blob 存儲着大量的二進制數據,而且 blob 的 size 和 type 屬性,都會被 file 對象所繼承。ios

                   因此, 在大多數狀況下,blob 對象和 file 對象能夠用在同一個地方,例如,可使用 FileReader 藉口從 blob 讀取數據,也可使用 URL.createObjectURL() 從 blob 建立一個新的 URL 對象。web

                 

                   這裏我先用了canvas一個最簡單的辦法,建立blob。canvas.toBlob(callback,type,quality);咱們能夠直接把上傳圖片的方法寫到回調裏面,type:類型(圖片:‘image/jpeg’),quality:圖片質量(0-1).ajax

                   固然這麼高級的方法確定會涉及到兼容性問題。那咱們就回到blob對象的問題上來吧。在chrome早先版本和目前的android中,至少是andrid5.1以前的瀏覽器,包括微信瀏覽器等,都不支持blob的構造方法,須要使用BlobBuilder。chrome

                   var file=new Blob( [array.buffer], {type : "image/jpeg"});//會存在兼容性問題。這個blob的構造方法,在ios手機瀏覽器是支持的,可是在android手機瀏覽器不行。 json

                   桌面版的chrome瀏覽器解決了這個blob bug, 可是android手機仍是有這個問題,會返回一個type error,由於android瀏覽器不支持這個構造方法。你必須使用老版本的BlobBuilder API.canvas

                   解決辦法:

                           

 //首先要將dataURL轉換爲Uint8Array對象:

               function dataURLtoBlob(dataurl) {
                            var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
                                bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
                            while(n--){
                                 u8arr[n] = bstr.charCodeAt(n);
                                }
                            return  u8arr ;
                         } 
            // 接下來的事情就好辦多了,來一發兼容性blob寫法:
            try{
                var jpeg = new Blob( [array], {type : "image/jpeg"});
               }
            catch(e){
             // TypeError old chrome and FF
             window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;
             if(e.name == 'TypeError' && window.BlobBuilder){
                 var bb = new BlobBuilder();
                 bb.append([array.buffer]);
                 var jpeg = bb.getBlob("image/jpeg");
            }
            else if(e.name == "InvalidStateError"){
                 // InvalidStateError (tested on FF13 WinXP)
                  var jpeg = new Blob( [array.buffer], {type : "image/jpeg"});
            }
           else{
                // We're screwed, blob constructor unsupported entirely
             }
           }

  

上傳到阿里雲:
我查了一下阿里雲的web直傳的Js示例代碼,感受寫的有點複雜,仍是用ajax來解決這個問題吧,仍是先上代碼再來大體講一下這個問題吧。

                   

  Utils.ajax({
                            url: url1,//url1是先向後臺請求上傳阿里雲的一些參數接口
                            success: function (res) {
                                    if (res.errorCode == 0) {
                                           var ossData=new FormData();
                                                 ossData.append("OSSAccessKeyId",res.data.accessId);//Bucket 擁有者的Access Key Id。
                                                 ossData.append("policy",res.data.policy);//policy規定了請求的表單域的合法性
                                                 ossData.append("Signature",res.data.signature);//根據Access Key Secret和policy計算的簽名信息,OSS驗證該簽名信息從而驗證該Post請求的合法性
                                                 //---以上都是阿里的認證策略
                                                ossData.append("key",res.data.dir+'/'+res.data.filename+'.jpg');//文件名字,可設置路徑
                                               ossData.append("success_action_status",'200');// 讓服務端返回200,否則,默認會返回204
                                               ossData.append('file', jpeg);//須要上傳的文件 file 這個
                                               //接下來就是上傳阿里雲了的代碼了
                                              //ossData.append("callback",callbackbody);//回調,非必選,能夠在policy中自定義
                                              $.ajax({
                                                        url : res.data.host, //上傳阿里地址
                                                         data : ossData,
                                                        processData: false,//默認true,設置爲 false,不須要進行序列化處理
                                                        cache: false,//設置爲false將不會從瀏覽器緩存中加載請求信息
                                                        async: false,//發送同步請求
                                                       contentType: false,//避免服務器不能正常解析文件---------具體的能夠查下這些參數的含義
                                                       //dataType: 'JSON',//不涉及跨域 寫json便可
                                                        type : 'post',
                                                       success : function(callbackHost, request) {}, //callbackHost:success,request中就是 回調的一些信息,包括狀態碼什麼的
                                                       error : function() {
                                                                   alert("圖片上傳出錯!")
                                                      }
                                                });
                                      }
                                 }
                            });

  

              其實Utils.ajax和$.ajax都是同樣的,爲了區分我這樣寫的,Utils.ajax的請求是爲了獲得後臺的驗證。上傳阿里雲的一些證書啊,驗證碼什麼的。$.ajax就是上傳到阿里雲的請求。值得注意點是:

              ossData.append('file', jpeg);//須要上傳的文件 file 這個jpeg就是咱們前面建立的blob。通常上傳到阿里雲成功後若是不返回任何東西,就不要寫入dataType了。

     

     過程大概就是這樣,參考了幾我的的文章推薦給你們:https://www.cnblogs.com/flicat/p/5337054.html       TypeArray、ArrayBuffer、Blob、File、DataURL、canvas的相互轉換

                                  http://blog.csdn.net/u012811805/article/details/53885008  移動端UC瀏覽器不支持Blob的解決方案

                                                                                           https://www.cnblogs.com/mottled/p/6979536.html              阿里OSS ajax方式 web直傳

相關文章
相關標籤/搜索