HTML5 Mobile Upload

淡淡的烟草味﹌ 2022-08-03 00:28 228阅读 0赞

HTML5移动端图片上传并前端预览

用到了HTML5的FileReader对象,主要思想是由于移动端的网络不比PC快,故需要做上传前预览,采用base64编码目前是比较好的方法。前端用FileReader获取图片并转为base64编码并预览,上传到服务器由后台解码生成图片并保存到磁盘。

核心代码:

  1. $('input[type=file]').change(function(){
  2. /*文件上传loadding*/
  3. $('#upload_loading').css('display','block');
  4. var vtop=$("body").scrollTop()+120;
  5. $('.pop-loading').css('top',vtop);
  6. /*定义对象变量*/
  7. var liObj=$(this).parent('a').parent('li');
  8. var aObj=$(this).parent('a.cert-btn-blue-add');
  9. var liidx=liObj.index();
  10. var fileval=$(this).val();
  11. var oFile=this.files[0];
  12. /*文件格式验证*/
  13. var fileval=$(this).val();
  14. var suffix=fileval.substring(fileval.lastIndexOf('.')+1,fileval.length);
  15. if(suffix!='jpg' && suffix!='png' && suffix!='jpeg'){
  16. alert('上传文件类型需为jpg、jpeg、png图片格式');
  17. liObj.find('input[type=file]').val('');
  18. $('#upload_loading').css('display','none');
  19. return false;
  20. }
  21. /*文件大小验证限制*/
  22. if(oFile.size>1024*512*1){
  23. alert('图片超过512kb,请到PC端官网上传');
  24. liObj.find('input[type=file]').val('');
  25. $('#upload_loading').css('display','none');
  26. return false;
  27. }
  28. /*图片预览及上传*/
  29. setTimeout(function(){
  30. var oReader = new FileReader();
  31. oReader.onload = function(e){
  32. var sBase64 = e.target.result;
  33. if(window.gIsAndroid && sBase64.indexOf("data:image/") != 0){
  34. var sMime = sName.split(".").pop().toLowerCase();
  35. sBase64 = sBase64.replace("base64,", "image/" + sMime + ";base64,");
  36. }
  37. var src=sBase64;
  38. var img = new Image();
  39. img.onload = function () {
  40. liObj.append(img);
  41. liObj.find('a.cert-arrow-del').show();
  42. };
  43. img.src = typeof src === 'string' ? src : URL.createObjectURL(src);
  44. /*压缩后重新图片赋值*/
  45. //var obj = compress(img,70);
  46. //img.src=obj.newImageData;
  47. aObj.hide();
  48. hasimgArr[liidx-1]=true;
  49. sBase64 = null;
  50. e.target.result=null;
  51. /*上传到服务器*/
  52. $.ajax({
  53. type:"POST",
  54. timeout:20000,
  55. url:"upfilehtml.do",
  56. data:{filebase64:src,size:src.length},
  57. dataType: "json",
  58. success: function(data){
  59. if(data.flag){
  60. }else {
  61. alert('上传失败,建议到PC端官网上传');
  62. liObj.find('img').remove();
  63. liObj.find('a.cert-arrow-del').hide();
  64. liObj.find('a.cert-btn-blue-add input').val('');
  65. setTimeout(function(){
  66. aObj.show();
  67. },100);
  68. }
  69. $('#upload_loading').css('display','none');
  70. src=null;
  71. }
  72. });
  73. };
  74. oReader.readAsDataURL(oFile);
  75. },500);
  76. });

压缩代码(采用canvas画图再toDataURL转为图片base64编码),代码如下:

  1. function compress(source_img_obj, quality, output_format) {
  2. var mime_type = "image/jpeg";
  3. if(output_format!=undefined && output_format=="png"){
  4. mime_type = "image/png";
  5. }
  6. var cvs = document.createElement('canvas');
  7. cvs.width = source_img_obj.width;
  8. cvs.height = source_img_obj.height;
  9. var ctx = cvs.getContext("2d").drawImage(source_img_obj, 0, 0);
  10. var newImageData = cvs.toDataURL(mime_type, quality/100);
  11. return {
  12. "newImageData": newImageData
  13. };
  14. }

知识点:

1.使用HTML5的FileReader对象,把图片存在内存,读取e.target.result的base64编码,前端预览

2.使用canvas画img,然后使用canvas的toDataURL方法进行转码成base64编码并压缩。把压缩后的base64赋给img src属性上。

3.把base64值传给后台,后台进行解码并保存为图片。

遇到的问题:

1.兼容性,拍照图片太大手机内存不够响应不过来,会刷新页面。我的手机(华为荣耀3C 移动4G),拍照默认最小为2592*1456,就出现这种问题。而用chrome,UC浏览器则无此问题。UC调手机照相机默认800*600;故加了图片大小限制及提示。

(注1:经测试,我这个项目一个页面上传6张图,而上传1-4张时则无此问题,猜想是拍照太多拍照进程未清除造成手机内存不足引起,不确定待讨论研究。)

(注2:调用摄像头拍照时,有以上问题,直接图库选图无此问题,图库选图过大的话只有上传太慢的不好体验)

2.canvas压缩问题,压缩后的base64码在PC上模拟无问题可以正常显示,而在手机上有些浏览器上则不显示图片。而chrome,UC浏览器无此问题。

(注:拍照,图库选图都未成功)

注意点:

1.上传完或base64使用完需设置为null,减少内存占用。

2.由于有多个上传,故每个上传时添加蒙层‘正在上传中..’作为提示,避免用户快速点击多次上传造成响应不过来。

3.添加图片大小验证控制,避免上传太大的图造成服务器响应过慢,一直Loading问题。(由于压缩不兼容问题,目前也只能这样做了,移动端不要上传太大的图,大小视服务器上传返回响应而定)

4.同一页面上传图片较多(此项目为6张图)容易引起以上问题出现。

有大神写的上传本地预览插件localResizeIMG也存在以上相关兼容问题,目前未找到能兼容所有移动端浏览器的完美方法。

插件地址:https://github.com/think2011/localResizeIMG3/

最后附上源码:

FileReader Demo

插件Demo

发表评论

表情:
评论列表 (有 0 条评论,228人围观)

还没有评论,来说两句吧...

相关阅读

    相关 HTML5 Mobile Upload

    HTML5移动端图片上传并前端预览 用到了HTML5的FileReader对象,主要思想是由于移动端的网络不比PC快,故需要做上传前预览,采用base64编码目前是比较好的方

    相关 HTML&HTML5

    HTML&HTML5 学习笔记 职坐标网上视频课程 ![这里写图片描述][SouthEast] ![这里写图片描述][SouthEast 1] ![这里写图片描述