zoukankan      html  css  js  c++  java
  • 关于H5裁剪图片后,直传阿里云的一些问题

      这段时间在工作中碰到一个需要在h5裁剪图像,然后直传阿里云的需求。图中遇到了一些小问题,分享出来大家都看看。

     h5裁剪图像:cropper.js是一个神器啊关于用法,网上可以收罗出大量的帖子,这里我就不多说了,大致原理就是利用canvas裁剪图像然后生成base64的图像(canvas.toDataURL('image/jpeg'))。

     转换Blob对象:接下来就是重点了,上传图片我们比较传统的做法就是将 canvas.toDataURL('image/jpeg')  传到后台,然后后台再生成图片传到阿里云。

                       这样就显得比较繁琐了,怎么将 canvas.toDataURL('image/jpeg')直接传到阿里云?这就懵逼了。这里不得不提到js的另一个东西,Blob对象。

                       file对象大家都不陌生了,那这个blob又是个什么鬼呢?而实际上 file 对象只是 blob 对象的一个更具体的版本,blob 存储着大量的二进制数据,并且 blob 的 size 和 type 属性,都会被 file 对象所继承。

                       所以, 在大多数情况下,blob 对象和 file 对象可以用在同一个地方,例如,可以使用 FileReader 借口从 blob 读取数据,也可以使用 URL.createObjectURL() 从 blob 创建一个新的 URL 对象。

                     

                       这里我先用了canvas一个最简单的办法,创建blob。canvas.toBlob(callback,type,quality);我们可以直接把上传图片的方法写到回调里面,type:类型(图片:‘image/jpeg’),quality:图片质量(0-1).

                       当然这么高级的方法肯定会涉及到兼容性问题。那我们就回到blob对象的问题上来吧。在chrome早先版本和目前的android中,至少是andrid5.1之前的浏览器,包括微信浏览器等,都不支持blob的构造方法,需要使用BlobBuilder。

                       var file=new Blob( [array.buffer], {type : "image/jpeg"});//会存在兼容性问题。这个blob的构造方法,在ios手机浏览器是支持的,但是在android手机浏览器不行。 

                       桌面版的chrome浏览器解决了这个blob bug, 但是android手机还是有这个问题,会返回一个type error,因为android浏览器不支持这个构造方法。你必须使用老版本的BlobBuilder API.

                       解决办法:

                               

     //首先要将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直传


    
    
  • 相关阅读:
    RDIFramework.NET V3.3 WinForm版新增日程管理功能模块
    RDIFramework.NET V3.3 WinForm版角色授权管理新增角色对操作权限项、模块起止生效日期的设置
    RDIFramework.NET V3.3 Web版角色授权管理新增角色对操作权限项、模块起止生效日期的设置
    前端神器-神级代码编辑软件Sublime Text下载、使用教程、插件推荐说明、全套快捷键
    C# net request payload形式发送post请求
    RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2版本正式发布
    RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2->WinForm版本重构岗位授权管理界面更规范、高效与美观
    NET快速信息化系统开发框架 V3.2 ->WinForm部分全部重构为Dev风格界面
    NET快速信息化系统开发框架 V3.2 -> “用户管理”主界面使用多表头展示、增加打印功能
    SQLServer特殊字符/生僻字与varchar
  • 原文地址:https://www.cnblogs.com/mieQ/p/8196295.html
Copyright © 2011-2022 走看看