需求情景:
我要用H5做一个创建房间页面,注册时需要上传房间头像、房间名称、房间描述这三项,传到后台并提示用户创建成功。
页面很简单,跟后台也很快调试通了,能够创建成功。
可是,有一点忽略了,开发测试时用的头像图片只有20K左右,点击创建后反应很快就创建成功。
然而,在正式测试的时候,发现了一个严重问题,点击提交按钮后,等待响应时间太久(大约10—15秒),才提示注册成功,罪魁祸首就是头像上传的图片太大(有2.2M左右),未经压缩处理就上传后台,才导致此问题。
下面介绍下处理方法:
创建页面是这样的:
html代码:
<div id="mainBox">
<div class="upload_file" id="upload_file">
<input type="file" name="_avatar" id="file_head" onchange="javascript:setImagePreview();" />
</div>
<form action="" method="post" enctype="multipart/form-data" id="uploadForm">
<input type="hidden" name="user_id" id="user_id"/>
<div class="headBox wrap">
<div class="mask_upload" id="mask_upload"></div>
<img id="preview" width="-1" height="-1" style="display: none" />
<p class="head_p1">上传房间头像</p>
</div>
<div class="wrap iptBox cnameBox"><input type="text" name="clan_name" id="clan_name" placeholder="请输入房间名称" /></div>
<div class="wrap iptBox cdeclarBox"><input type="text" name="clan_declar" id="clan_declar" maxlength="15" placeholder="请输入房间描述(15个字以内)"/></div>
<div class="wrap">
<input type="button" value="创建" id="clan_create"/>
</div>
</form>
</div>
第一步:图片压缩
在图片压缩时,我用到了localResizeIMG插件。
github下载:https://github.com/think2011/localResizeIMG
基本原理是通过canvas渲染图片,再通过 toDataURL 方法压缩保存为base64字符串(能够编译为jpg格式的图片)。
引入插件:
扫描二维码关注公众号,回复:
1529159 查看本文章
<script type="text/javascript" src="localResizeIMG-master/dist/lrz.bundle.js" ></script>
js:
var base64; //图片压缩后转换成的base64字符串
//压缩并预览家族封面照片
function setImagePreview() {
//图片压缩
var img = document.querySelector('#file_head');
lrz(img.files[0])
.then(function (rst) {
// 处理成功会执行
console.log(rst);
base64 = rst.base64;
//将图片压缩后生成的base64串的值赋给img标签,显示预览
$('#preview').attr('src',base64);
})
.catch(function (err) {
// 处理失败会执行
})
.always(function () {
// 不管是成功失败,都会执行
});
}
第二步:上传图片等信息到后台
//点击创建,提交信息
$('#clan_create').on('click',function(){
sumitImageFile(base64);
})
//提交家族信息
function sumitImageFile(base64Codes){
var form=document.forms[0];
//连带form里的其他参数也一起提交
var formData = new FormData(form);
//convertBase64UrlToBlob函数是将base64编码转换为Blob
//append函数的第一个参数是后台获取数据的参数名,和html标签的input的name属性功能相同
formData.append("avatar",convertBase64UrlToBlob(base64Codes));
//ajax 提交form
$.ajax({
url : '创建房间接口url',
type : "POST",
data : formData,
dataType:"text",
processData : false, // 告诉jQuery不要去处理发送的数据
contentType : false, // 告诉jQuery不要去设置Content-Type请求头
success:function(result){
var ret = JSON.parse(result);
var rescode = ret.code;
if(rescode=='0'){
//提示房间创建成功
}
},
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图片数据
*/
function convertBase64UrlToBlob(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);
}
return new Blob( [ab] , {type : 'image/png'});
}
关于上述代码中FormData对象:
使用FormData,通过Ajax方式上传文件。
先创建一个空的FormData对象,然后再用append方法逐个添加键值对:
var formdata = new FormData();
formdata.append(“url”, “http://www.baidu.com/“);
具体用法可参考:http://blog.csdn.net/inuyasha1121/article/details/51915742