项目回顾1-图片上传-form表单还是base64-前端图片压缩

第一个项目终于上线了,是一个叫亲青筹的公益众筹平台,微信端,电脑端还有后台界面大部分都是我完成的,几个月过来,感觉收获了很多,觉得要总结一下。

首先想到的是图片上传的问题。在通常表单数据都是ajax上传的情况下,为了上传图片而去使用form表单感觉很蠢。然后那时候也没有想到用jquery form插件。

后台的同事给的方案是用iframe里写一个form表单,然后上传图片之后自动提交表单,他将图片在服务器上的地址以跳转页url的一部分,我再来截取的方式。

方案一:iframe+form表单

    <form action="/user/uploadIdCard.do" class="fileForm picUpload" enctype="multipart/form-data" method="post"><input type="file" id="uploadPic" name="file"><label for="uploadPic" id="fileBtn">+<img src="" /></label><input type="text" name="turnUrl" class="turnUrl"></form>

 

    $(".turnUrl").val(window.location.pathname);$("#uploadPic").on('change', function(event) {event.preventDefault();$("form").submit();});

在需要上传图片的界面引入iframe,在调用公用库里的iframe方法,获得图片的url并且把图片显示在iframe中

// 提取iframe里的路径
function iframe(el) {var baseurl = "";var code, filePath;var place = $(el)[0].contentWindow.location.search;console.log(place);if (place) {code = place.match(/code=\d+/)[0].substr(5);if (place.match(/filepath=\S+/)) {filePath = place.match(/filepath=\S+/)[0].substr(9);}$(el).contents().find(".tip").css('color', '#d0021b');console.log(filePath);switch (code) {case "200":$(el).contents().find(".tip").text('上传成功');$(el).contents().find(".tip").css('color', '#55a012');$(el).contents().find("#fileBtn>img").show().attr("src", baseurl + "/" + filePath);return "/" + filePath;case "206":$(el).contents().find(".tip").text('文件过大');break;case "207":$(el).contents().find(".tip").text('文件类型错误');break;case "208":$(el).contents().find(".tip").text('系统错误');}}
}

方案二:后来发现这样的做法有两个问题,一个是用户发的图片太大,后台没有做压缩(后台的同事太忙了,为了迁就他们,就我们前端做压缩了)。第二个是,上传图片成功之后,图片显示在iframe上,这样需要一定的反应时间,使用者有时候会反映图片传不上去,其实只是后台还没有返回……

于是决定用base64上传到后台的方式

    <input type="file" id="uploadPic" name="file"><label for="uploadPic" id="fileBtn">+<img class="showPic" src="" /></label><span class="tip">请上传图片,大小在2M以内<br/>(图片类型可为jpg,jepg,png,gif,bmp)<br/>推荐图片比例为640*400</span><input type="text" name="turnUrl" class="turnUrl"><canvas id="uploadImg" style="display:none"></canvas>

结构和原来差不多,只是多了一个canvas

    $("#uploadPic").on('change', function(event) {event.preventDefault();console.log($(this)[0].files);var file = $(this)[0].files[0];if(file.size>2097152){alert("上传图片请小于2M");return false;}        if (!/image\/\w+/.test(file.type)) {alert("文件必须为图片!");return false;}var reader = new FileReader();reader.readAsDataURL(file);reader.onload = function(e) {createCanvas(this.result);}
    });function createCanvas(src) {var canvas = document.getElementById("uploadImg");var cxt = canvas.getContext('2d');canvas.width = 640;canvas.height = 400;var img = new Image();img.src = src;img.onload = function() {// var w=img.width;// var h=img.height;// canvas.width= w;// canvas.height=h;cxt.drawImage(img, 0, 0,640,400);//cxt.drawImage(img, 0, 0);$(".showPic").show().attr('src', canvas.toDataURL("image/jpeg", 0.9));$.ajax({url: "/front/uploadByBase64.do",type: "POST",data: {"imgStr": canvas.toDataURL("image/jpeg", 0.9).split(',')[1]},success: function(data) {console.log(data);$(".showPic").show().attr('data-url',"/"+ data.url);}});}}

1.首先是用的input的file文件的信息,判断文件大小file.size,以及文件是否为图片file.type

2.再通过html5的FileReader接口来获得这个图片的base64数据

3.将这个base64传入canvas中,作为一张图的src,这时候可以设置图片的分辨率大小,保证上传的图都是统一的分辨率。当然也可以按照图片原来的大小。

4.在ajax之前,把处理后的base64直接显示出来(这样用户就可以立刻看到自己上传的图片),再将 canvas.toDataURL("image/jpeg", 0.9).split(',')[1] (类型为image/jpeg,就可以用第二个参数来设置画质了)传到后台对应的接口

5.再将后台返回的url 绑在图片的data-url属性上,在ajax上交整个表单时获取这个data-url就好了,这样用户可以最快时间看到,而url其实还在ajax到后台的过程中

后记:这两个方案都有一个问题,会给后台上传很多冗余图片。不过后台的同事貌似没什么意见,囧。

实际效果是这样的 http://www.qqchou.org/qqcweb/pages/photoIframe.html 

 

转载于:https://www.cnblogs.com/wzls/p/5714273.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/403371.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

4.6 【共享源】流的生产者(一)

一,什么是生产者? 生产者创建内容并与有权限的消费者共享。 作为生产者,必须相应地设置流以供消费。通常,我们需要在生产者应用程序中执行接下来的流程来共享产生的内容。 二,创建生产者的流 调用 screen_create_stream() 为生产者创建流以进行渲染。例如 ... screen…

vue路由传参两种方式;vue路由传参query与params区别;vue路由跳转的带参与不带参,路由跳转传参方式:name 、 path;

vue项目的路由传参常用的有两种方式&#xff1a;query和params 1.query传参特点&#xff1a;1.1可以用path也可以用name传递路径 注意name是路由页面vue文件的名称 不需要/1.2跳转页面地址栏可以看到路径和参数 通过 this.$route.query.id 可以获取到参数1.3刷新不会丢失参数t…

Qt下Undefined reference to 'vtable for xxx'

QT下遇到这种错误提示时候需要注意以下情况&#xff1a; 一、cpp文件里使用了Q_OBJECT 分析&#xff1a;qmake不会处理.cpp文件里的Q_OBJECT&#xff0c;所以如果在.cpp文件中有它的话将会产生undefined reference to vtable for "xxx::xxx"。 方法1&#xff1a;…

Realtek网卡如何识别具体型号是8111B/8111C/8111D还是8111E???

From: http://support.icafe8.com/technologynews/focus/1347.html 貌似在去年&#xff0c;Realtek网卡把型号都统一为Realtek GBE什么什么的这种名字&#xff0c;这个修改说实话&#xff0c;对有盘没啥影响&#xff0c;只要驱动装好&#xff0c;能上网就ok了&#xff0c;但是…

【leetcode77】Single Number

一题目描述&#xff1a; 给定一个数组&#xff0c;只有一个数字出现一次&#xff0c;其余都是两次&#xff0c;判断那个数字 思路&#xff1a; 不断取出数据进行异或&#xff0c;最后一个数字&#xff0c;因为相同的数字会抵消代码&#xff1a; public class Solution {public …

qDebug格式化输出类型

%a,%A——读入一个浮点值(仅C99有效)    %c——读入一个字符    %d——读入十进制整数    %i——读入十进制&#xff0c;八进制&#xff0c;十六进制整数    %o——读入八进制整数    %x,%X——读入十六进制整数    %s——读入一个字符串&#xff0c;遇空格、制…

linux服务器上jfreeChar乱码问题

更新服务器字体和jdk字库utf-8。

css的px、rpx、em、rem、vw、vh、vmin、vman的区别

px:绝对单位 1px在哪里长度都是一样 rpx&#xff1a;相对单位 微信小程序引入rpx单位 在屏幕像素基准为375物理像素的屏幕上 1rpx 1px 例如iph6是屏幕宽度是375px 750物理像素 那么在上1rpx 375/750px0.5px em&#xff1a;相对单位 基准点是父节点字体font-size大小 rem&…

mac系统如何显示和隐藏文件

From: http://www.cnblogs.com/lm3515/archive/2010/12/08/1900271.html 苹果Mac OS X操作系统下&#xff0c;隐藏文件是否显示有很多种设置方法&#xff0c;最简单的要算在Mac终端输入命令。显示/隐藏Mac隐藏文件命令如下(注意其中的空格并且区分大小写)&#xff1a;显示Mac隐…

数制转换

进制的转换可以借助强大的BigInteger&#xff0c;非常的方便。 new java.math.BigInteger(num, from).toString(to); 表示num要转换的数从from源数的进制 转换成to的进制。 题目描述 求任意两个不同进制非负整数的转换&#xff08;2进制&#xff5e;16进制&#xff09;&#xf…

QString与char *之间的转换

1. 在 Qt 下将 QString 转 char* 需要用到 QByteArray 类&#xff0c;QByteArray 类的说明详见Qt帮助文档。因为 char* 最后都有一个‘/0’作为结束符&#xff0c;而采用 QString::toLatin1() 时会在字符串后面加上‘/0’。Exp : Qstring str "helloworld"; char …

Remoting-1

什么是Remoting&#xff0c;简而言之&#xff0c;我们可以将其看作是一种分布式处理方式。从微软的产品角度来看&#xff0c;可以说Remoting就是DCOM的一种升级&#xff0c;它改善了很多功能&#xff0c;并极好的融合到.Net平台下。Microsoft .NET Remoting 提供了一种允许对象…

斐波那契数列;递归函数;爬楼梯问题;

斐波那契数列&#xff1a; 例如&#xff1a;一个人爬楼梯&#xff0c;每次只能爬1个或两个台阶&#xff0c;假设有n个台阶&#xff0c;那么这个人有多少种不同的爬楼梯方法&#xff1b; 1阶楼梯&#xff1a;1种方法 2阶楼梯&#xff1a;2种方法 3阶楼梯&#xff1a;3种方法 4阶…

QString包含中文时与char *转换

方法1&#xff1a; 添加GBK编码支持&#xff1a; #include <QTextCodec>QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));QString str; char *ch; QByteArray ba …

DEBUG 调试

1.Step Into (also F5) 跳入 2.Step Over (also F6) 跳过 3.Step Return (also F7) 执行完当前method&#xff0c;然后return跳出此method 4.step Filter 逐步过滤 一直执行直到遇到未经过滤的位置或断点(设置Filter:window-preferences-java-Debug-step Filtering) 5.resume 重…

Asp.net web Api源码分析-HttpParameterBinding

接着上文Asp.net web Api源码分析-Filter 我们提到filter的获取和调用&#xff0c;后面通过HttpActionBinding actionBinding actionDescriptor.ActionBinding;来获取HttpActionBinding实例&#xff0c;然后调用 HttpActionBinding的ExecuteBindingAsync方法来绑定Action参数。…

TCP/IP详解卷1中文版勘误表前言

相信仔细阅读过TCP/IP这一经典著作中文版的读者们最痛苦的就是其中一些语句或者词汇感觉无法理解&#xff0c;其后果要么是无法理解&#xff0c;要么理解错误&#xff0c;如果错误的概念在脑中根深蒂固了&#xff0c;对于以后的学习和工作将是十分令人苦恼的事情。看到多数读者…

promise使用详解

原文链接以及promise练习题 先说结论&#xff1a; promise是解决异步函数的一种方案 将异步操作以同步方式展现出来 避免了回调地狱 1.三种状态&#xff1a;padding–等待 resolved–成功–then rejected–失败–catch 2.promise上有then和catch方法 then接受一个参数是函数 这…

vim 使用中的一些错误[omnifunc未设置错误]

From: http://blog.sina.com.cn/s/blog_60c70b6c01015b43.html 1.option ‘omnifunc’ is notset 错误: vim7下Omnicompletion默认情况下是没有开启的&#xff0c;有时候自定义的vimrc文件会实现自动补齐&#xff0c;例如vim-autocomplpop等等&#xff0c;在编辑html/css文件的…

Sqlite 管理工具收藏

1.SQLite Administrator http://download.orbmu2k.de/files/sqliteadmin.zip 2.SQLite2009Pro-v3.8.3.1 http://osenxpsuite.net/SQLite2009Pro-v3.8.3.1.zip 3.SqliteDev http://www.sqlitedeveloper.com/downloads/SqliteDev450.zip 4.sqlite_maestro_executable已破解.rar…