最近在使用mui做一几个页面,需要拍照后上传到服务器一些图片。其中在上传之前,可多选择多张,可以预览,可以缩放,可以删除,因此在这个过程中也找了不少的知识点,也走了不少的弯路,写在这里,为了分享与查询。
这次分享的知识点:
FormData 为二进制异步上传方法,上传的数据与文件是 1:1 的
Base64 为二进制数据表示方法,文件越大,体积越大,可用在 canvas 裁切预览,预览本地图片在浏览器上,不建议在上传时使用。转成base64之后,最大的好处就是可以绘制到Canvas上,然后对图片进行编辑!
jQuery.form 为二进制异步上传方法
如果在上传前,图片文件已经转成 Base64 ,但是想要通过 FormData 上传文件时,需要将 Base64 转成 Blob 对象,最后将 Blob 对象 append 到 FormData 中,将FormData做为参数上传到服务器。所以有句话叫做:
既然都用FormData了,还转个毛线base64啊!
下面分别介绍:
预览功能:
http://www.jb51.net/article/4...
http://www.jb51.net/article/7...
https://www.oschina.net/code/...
获取上传前,存在浏览器中的图片地址(或对象)
input.on.('change', preview);
function preview(e) {
// 获取到input-file的文件对象
var file = e.target.files[0];
...
}
浏览器缓存图片的base64 [ window.URL.createObjectURL(file) ]
// 结果: "blob:null/1342ae24-b5da-4ec3-b05d-f385387bd881"
window.URL.createObjectURL(document.getElementById('imgOne').files[0]);
//JS预览图像将本地图片显示到浏览器上
document.getElementById(' imgPre ').src=' blob:null/1342ae24-b5da-4ec3-b05d-f385387bd881 ';
实际上传图片的base64 [ new FileReader().readAsDataURL (file) ]
var reader = new FileReader();
reader.onloadend = function () {
// Base64内容
preview.src = reader.result;
}
reader.readAsDataURL( document.querySelector('input[type=file]').files[0] );
利用 canvas 在浏览器中实现预览
var img = new Image();
img.onload = function () {
// 当图片宽度超过 400px 时, 就压缩成 400px, 高度按比例计算
// 压缩质量可以根据实际情况调整
var w = Math.min(400, img.width);
var h = img.height * (w / img.width);
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
// 设置 canvas 的宽度和高度
canvas.width = w;
canvas.height = h;
// 把图片绘制到 canvas 中
ctx.drawImage(img, 0, 0, w, h);
// 取出 base64 格式数据
var dataURL = canvas.toDataURL('image/png');
// ...
};
img.src = reader.result;
压缩功能:
压缩没怎么研究,从网上找的相对可用的资源,贴在这里,方便查询
javascript - 在移动端怎样上传图片?,而且在上传前把图片压缩一定的大小?
https://segmentfault.com/q/10...
借助插件 lrz.mobile.min.js
[lrz.bundle.js 前端图片压缩] think2011/localResizeIMG: 前端本地客户端压缩图片,兼容IOS,Android,PC、自动按需加载文件
https://github.com/think2011/...
上传前的图片压缩逻辑之一,就是在前端把base64转成二级制数据,这个数据体积相比base64小很多,还可以塞到formdata中提交
我在我的项目中有用到过,是因为图片需要预览,也需要上传,总体感觉不太好。
Base64异步提交
利于canvas,实现图处在线预览
利用new FileReader,实现图片转Base64
读出 base64
function preview(e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.onloadend = function () {
// 图片的 base64 格式, 可以直接当成 img 的 src 属性值
var dataURL = reader.result;
var img = new Image();
img.src = dataURL;
// 插入到 DOM 中预览
// ...
};
// 读出 base64
reader.readAsDataURL(file);
}
base64 转 二进制文件,也就是base64 转blob
function dataURItoBlob(dataURI) {
var byteString = atob(dataURI.split(',')[1]);
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ab], {type: mimeString});
}
blob对象是可以通过 FormData 异步提交的
var imgaeBlob = dataURItoBlob(dataURI);
var formData = new FormData();
formData.apppend('images',imgaeBlob);
mui.ajax({
type: "post",
url: url,
data: formData,
cache: false,
processData: false,
contentType: 'enctype="multipart/form-data'
});
jQuery.form异步提交
使用jQuery.form插件,实现完美的表单异步提交
http://www.cnblogs.com/heyuqu...
两种实现表单提交的方法
var options = {
url: 'async_submit_test1.aspx?action=SaveUserInfo',
type: 'post',
dataType: 'text',
data: $("#form1").serialize(),
success: function (data) {
if (data.length > 0)
$("#responseText").text(data);
}
};
$.ajax(options);
与
var options = {success: function (data) {$("#responseText").text(data);} };
// ajaxForm
$("#form1").ajaxForm(options);
// ajaxSubmit
$("#btnAjaxSubmit").click(function () {
$("#form1").ajaxSubmit(options);
});
FormData异步提交:
post,提交时的 contentType,影响返回的数据的查看(我是这么理解的):
application/x-www-form-urlencoded (常见的)
multipart/form-data (图片文件上传时常设置)
如果在提交的表单中除了图片外还有其它类型的,必须分别 appentd 到 formData 中
application/x-www-form-urlencoded 这种格式最为常见,平时使用的ajax提交就是这种方式。对应postman上的x-www-form-urlencoded选项,请求头中Content-Type为application/x-www-form-urlencoded;charset=utf-8,其中请求的数据被编码为key=value&key=value的形式(没错,类似浏览器地址栏中的get请求参数拼接方式),其具体值是编码好的:
multipart/form-data 当表单提交内容中包含文件时(比如图片文件),则需要这种数据格式。通常要设置表单enctype="multipart/form-data":
如果有text的input,可以这样写。如果有多个值,可以多次 append():
var formData = new FormData();
formData.append("images[]", fileBlob);
formData.append('text',ticketDes);
$.ajax({
type: "post",
url: dd.baseUrl + '/save.html',
data: formData,
cache: false,
processData: false,
contentType: 'enctype="multipart/form-data',
sucess:function(data){}
});
网上找了一些相关的方法与demo:
使用FormData对象提交表单及上传图片
http://blog.csdn.net/fdipzone...
FormData将图片转为 base64 上传
var fromData = new FormData();
fromData.append("base64", e.target.result);
通过FileReader获取图片的base64
http://www.cnblogs.com/simonb...
FormData 自定义(二进制)上传
var fd = new FormData();
var blob = dataURItoBlob(dataURL);
fd.append('file', blob);
dataURI 为 base64
function dataURItoBlob(dataURI) {
var byteString = atob(dataURI.split(',')[1]);
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ab], {type: mimeString});
}
利用FileReader和FormData实现图片预览和上传
http://www.tuicool.com/articl...
欢迎指点,指错!谢谢!