关于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直传
关于H5裁剪图片后,直传阿里云的一些问题的更多相关文章
- base64格式的图片上传阿里云
base64格式的图片上传阿里云 上传图片的时候,除了普通的图片上传,还有一张图片信息是以base64格式发送到后台的. 后台接受base64格式的图片,上传至阿里云代码:(主要是将base64转化成 ...
- 微信小程序中图片上传阿里云Oss
本人今年6月份毕业,最近刚在上海一家小公司实习,做微信小程序开发.最近工作遇到一个小问题. 微信小程序图片上传阿里云服务器Oss也折腾了蛮久才解决的,所以特意去记录一下. 第一步:配置阿里云地址: 我 ...
- 百度editor调用【图片上传阿里云】
百度editor调用简单,但是图片和文件上传阿里云就有点难度了.下面我详细说一下. 百度富文本编辑器下载地址:http://ueditor.baidu.com/website/download.htm ...
- 如何用云存储和CDN加速网站图片视频、阿里云OSS的使用(转)
总有人说阿里云主机带宽小,那只是因为你还停留在单机架构上. 阿里的架构设计,云主机主要用来跑程序的,附件的存储和访问主要靠OSS. 有人又会说了,OSS按存储费+流量双重计费伤不起,只是你不知道OSS ...
- Sts 授权直传阿里云 OSS-.net core实现
前言 磁盘怎么又满了?赶紧 快 打电话给运维扩容扩容扩容!这个问题已经是我入职新公司两个月来,第 3 次听到了.经过一通了解,事情原来是这样的.虽然我们使用了阿里云的 OSS 对象存储服务,但是为了不 ...
- jquery photoClip支持手机端,PC端 本地裁剪图片后上传插件
支持手机,PC最好的是jquery photoClip插件,下载地址&示例:https://github.com/topoadmin/photoClip demo.html 代码: <! ...
- 微信小程序裁剪图片后上传
上传图片的时候调起裁剪页面,裁剪后再回调完成上传; 图片裁剪直接用we-cropper https://github.com/we-plugin/we-cropper we-cropper使用详细 ...
- 小程序踩坑记录-上传图片及canvas裁剪图片后上传至服务器
最近在写微信小程序的上传图片功能,趟过了一些坑记录一下. 想要满足的需求是,从手机端上传图片至服务器,为了避免图片过大影响传输效率,需要把图片裁剪至适当大小后再传输 主要思路是,通过wx.choose ...
- C# .net Ueditor实现图片上传到阿里云OSS 对象存储
在学习的时候,项目中需要实现在Ueditor编辑器中将图片上传到云储存中,老师演示的是上传到又拍云存储,既然看了一遍,直接照搬不算本事,咱们可以依葫芦画瓢自己来动手玩玩其它的云存储服务. 现在云计算产 ...
随机推荐
- spark自定义函数之——UDF使用详解及代码示例
前言 本文介绍如何在Spark Sql和DataFrame中使用UDF,如何利用UDF给一个表或者一个DataFrame根据需求添加几列,并给出了旧版(Spark1.x)和新版(Spark2.x)完整 ...
- android:两个应用之间怎样传值之activity
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/zjh171/article/details/37738579 两个应用之间怎样传值.事实上这个标题太 ...
- c++隐藏运行exe黑窗口
加入main方法隐藏窗口 HWND hwndDOS = GetForegroundWindow(); ShowWindow(hwndDOS, SW_HIDE);
- Caused by: android.view.InflateException: Binary XML file line #18: Binary XML file line #18: Error inflating class android.widget.CheckedTextView
困扰了我一天啊 终于吧 这个大bug 给解决掉了 可能是 当时懵逼了 竟然忘记重新构造了!!尴尬了 直接把项目的 build 文件删除重新构造了一边!!
- Makefile 从入门到放弃
//如有侵权 请联系我进行删除 email:YZFHKM@163.com { 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作, ...
- 【转载】opencl中设备内存
地址空间限定符 一般的内核代码中,里面的内核参数或声明变量时,都会有地址空间限定符 地址空间限定符,地址空间限定符的主要作用是指出数据应该保存在哪个地方 地址空间限定符有4个: 全局内存: 限定符:_ ...
- System.Web.Mvc.ControllerBase.cs
ylbtech-System.Web.Mvc.ControllerBase.cs 1.程序集 System.Web.Mvc, Version=5.2.3.0, Culture=neutral, Pub ...
- (36)C# COM交互
调用DLL [DllImport("standerMFC.dll")] public static extern int PReadUID(ref HHFC_SET stru); ...
- import time 进度条动态输出26个字母
# 2018-08-06 19:42:51 import time # 调用时间模块 num = 97 # 字母a while num <= 115: # print(chr(num), end ...
- 第四周课堂笔记3th
1.函数的嵌套 作用域,说的是变量 全局作用域:内置命名空间,全局命名空间 全局空间不可以引用局部空间 局部作用域: 局部命名空间 开辟的临时空间前提是调用了函数 全局作用域在整个文件中被使用 L ...