iframe方法实现表单文件上传,页面无刷新
2018-01-03 18:58
716 查看
表单上传
需求:网站需要安装控件,只能在IE中打开
实现数据(字符串、文件)的上传
上传时通过图片验证码,文件大小、格式验证
兼容IE8+
一开始不知道网站只能在IE中打开,而且还得兼容IE8。初始的方法使用的是
ajax,
FormData()和
input的
FileList属性,可以通过这个FileList获取文件的文件名,文件大小,文件类型等
var formData = new FormData(); formData.append("name", $("[name=username]").val()); // 字符串 ... formData.append("file", document.getElementById("file").files[0]); // 文件 $.ajax({ url: urlStr, type: "POST", data: formData, processData: false, contentType: false, success: function (data) {}, error: function(error) })
使用点:
XMLHttpRequest Level 2新增的
FormData,兼容性为IE10+
input标签
type为
file时的files属性,兼容性为IE10+
FormData input file属性
遇到的兼容问题:
IE89无法读取文件的FileList属性,也就无法获取文件的大小和MIME
图片验证码时使用input事件,当输入的内容
trim()后长度等于4时,发送验证请求,IE8对
onInput不支持(兼容性查看),
模拟表单按钮,点击label时无法唤起
display: none;的
input
分析:
无法使用ajax的
FormData,那只能使用浏览器原生的
Form功能。
<form class="pure-form pure-form-aligned" action="/cos/rest/complain/advice.json" method="POST" target="formsubmit" enctype="multipart/form-data" onsubmit="return funcFormCheck();"></form>
action指向后台提供的接口
method设置HTTP的方式
target后台返回的数据写入target的页面,这里面写入本地隐藏的一个
iframe,通过给这个iframe绑定load事件去获取里面的内容,类似ajax中
success的
data。
enctype设置form上传的格式,默认为
application/x-www-form-urlencoded(将参数附到url后面,类似
baidu.com/?name=hell)
onsubmit表单提交前触发,可以通过这个属性做JS方面的验证,建议看这篇blog,从
prototype分析该属性。
ps:
有些情况下,后台返回的JSON文件会被IE浏览器下载,而不是写在iframe里。那是因为IE浏览器不支持
application/json形式文件。此处可以让后台同学设置返回json文本的
contentType为
text/html。
IE8不支持input的onInput事件,无法在输入验证码时无痛验证,此处通过给当前input绑定
keyup事件,来准确监听value的长度,并发出验证请求。
为了避免空格出现影响字符长度判断,使用
trim(),但是IE8不支持
trim(),通过向
String的
prototype添加
trim()方法
我们可以通过FileList属性获取文件的MIME,通过我们也可以在
<input type="file" accept="image/*, text/*">
accept属性直接限制,但是IE89不支持该属性。
<!--提供输入框验证插件,如果验证通过则返回true--> <script src="/etc/designs/gtja_v2/default/themes/js/formValid2.js"> </script> <!--提示框插件--> <script src="/etc/designs/gtja_v2/default/shared/clientlibs/js/plugin/layer/layer.js"></script> <script src="/etc/designs/gtja_v2/default/themes/js/base64.js"></script> <iframe name="formsubmit" id="formsubmit" style="display: none"></iframe> <div class="inside form-complain"> <div class="formbox"> <h3>投诉与建议内容</h3> <form class="pure-form pure-form-aligned" action="/cos/rest/complain/advice.json" method="POST" target="formsubmit" enctype="multipart/form-data" onsubmit="return funcFormCheck();"> <input class="login-token" type="hidden" name="loginToken"> <div class="pure-control-group"> <div class="input-label"> <em class="red">*</em> 您的姓名:</div> <input class="ele-input" name="name" type="text" data-valid-list="" data-type="noEmpty" placeholder="请输入您的姓名"> <span class="error-place"></span> </div> <div class="pure-control-group"> <div class="input-label"> <em class="red">*</em> 联系电话:</div> <input class="ele-input" name="phoneNo" type="text" data-valid-list="" data-type="phone" placeholder="请输入您的联系电话"> <span class="error-place"></span> </div> <div class="pure-control-group"> <div class="input-label"> <em class="red">*</em> 邮箱地址:</div> <input class="ele-input" name="mailAddr" type="text" data-valid-list="" data-type="email" placeholder="请输入您的邮箱"> <span class="error-place"></span> </div> <div class="pure-control-group"> <div class="input-label"> <em class="red">*</em> 反馈概要:</div> <input class="ele-input" name="desc" type="text" data-valid-list="" data-type="noEmpty" placeholder="请输入您要反馈的主题"> <span class="error-place"></span> </div> <div class="pure-control-group"> <div class="input-label"> <em class="red">*</em> 反馈内容:</div> <textarea class="ele-textarea" name="content" maxlength="200" placeholder="请详细说明您要反馈的问题或为我们提供建议" data-valid-list="" data-type="noEmpty"></textarea> <span class="error-place"></span> </div> <div class="pure-control-group"> <div class="input-label"> 附件上传:</div> <label class="labelFile" style="background-color:#004e98;color:#ffffff" for="file">点击上传文件</label> <span class="error-place filename"></span> <input name="file" id="file" class="file hide" type="file" placeholder="上传附件"> <img class="icon-del" src="/etc/designs/gtja_v2/default/themes/images/icon-remove.png" alt="删除文件"> <span style="display:block;margin-left:160px;color:#b2b2b2;font-size:11px">(如有附件可进行上传,不超过5MB,可上传docx,doc,xls,jpg等格式文件)</span> </div> <div class="pure-control-group"> <div class="input-label"> <em class="red">*</em> 验证码:</div> <input id="foo" class="foo ele-input" type="text" placeholder=""> <img class="captchaImage" src="http://180.163.109.16/cos/rest/stock/captchaImage" height="32" width="100" onclick="changeCaptcha(this)" title="看不清楚?点击换一张"> <span class="error-place"></span> </div> <div class="pure-controls"> <input type="submit" class="pure-button pure-button-primary btn-sub" value="提交"> <input type="reset" class="pure-button" value="重置"> </div> </form> </div> </div> <script> String.prototype.trim = function() { return this.replace(/(^\s*)|(\s*$)/g, ""); } var urlStr = ""; var address = $.base64.btoa(encodeURIComponent(location.protocol + '//' + location.host + '/cos/rest/complain/transport')); $(document).ready(function() { $.ajax({ url: urlStr+"/cos/rest/complain/checkLogin.json", dataType: 'json', success: function (data) { if (data.isLogin === false) { layer.open({ title: '提示', content: '您当前还未登录,请登录后重试', success: function (index, layero){ window.setTimeout(function (){ window.location.href = 'http://mall.gtja.com/loginweb/login?nextUrl=' + address; },2000) }, yes: function (index, layero) { window.location.href = 'http://mall.gtja.com/loginweb/login?nextUrl=' + address; } }); } }, error: function (error, status) { layer.open({ title: '提示', content: '服务器或网络错误,请登录后重试', success: function (index, layero){ window.setTimeout(function (){ window.location.href = address; },2000) }, yes: function (index, layero) { window.location.href = address; } }); } }) }); function getLoginToken() { var str = location.search; var equalIndex = str.indexOf('='); return str.substr(equalIndex + 1) } $(".login-token").val(getLoginToken()); function funcFormCheck() { if ($(".formbox").formValid() && imgVerifyFlag && fileVerifyFlag) { return true; } else { return false; } } $("#formsubmit").load(function() { var SbodyContent = $(window.frames['formsubmit'].document.body).text(); if(SbodyContent !== '') { var oBodyContent = JSON.parse(SbodyContent) if (oBodyContent.isLogin === true) { if (oBodyContent.sendStatus === true) { layer.open({ title: '提示', content: '投诉与建议内容发送成功' }); } else { layer.open({ title: '提示', content: '投诉与建议内容发送失败,请重试' }); } } else { layer.open({ title: '提示', content: '登录超时,请登录后重试', yes: function (index, layero) { window.location.href = address; } }); } } }); var checkCodeUrl = urlStr + '/cos/rest/stock/checkCode.json'; var imgVerifyFlag = false; // 切换图片二维码 function changeCaptcha(obj) { obj.src = urlStr + "/cos/rest/stock/captchaImage?" + Math.random(); } $(".foo").on("keyup", function () { var $this = $(this); imgVerifyFlag = false; if ($this.val().trim().length === 4) { $.ajax({ url: checkCodeUrl, data: { captcha: $this.val() }, dataType: 'json', success: function (data) { if (data.verification === false) { imgVerifyFlag = false layer.open({ title: '提示', content: '请输入正确的图片验证码' }); } else { imgVerifyFlag = true } }, error: function (error, status) { layer.open({ title: '提示', content: '网络错误,请点击图片验证码,获取新的验证码' }); } }) } }); var fielRep = /image|wordprocessingml|spreadsheetml|excel|msword/ var fileVerifyFlag = true $("#file").on("change", function () { var $this = $(this); fileVerifyFlag = false; if (this.files !== undefined && this.files.length > 0) { var fileObj = this.files[0]; if ((fileObj.size / 1024 / 1024) > 5 || !fielRep.test(fileObj.type)) { layer.open({ title: '提示', content: '请上传不大于5M的word文档,表格或者图片' }); $this.val(''); fileVerifyFlag = true } else { fileVerifyFlag = true $(".filename").text(fileObj.name); $(".filename").show(); $(".icon-del").show(); } } else { var path = $this.val(); var fakeLen = 'fakepath'.length; var fName = path.substr(path.indexOf('fakepath') + fakeLen + 1); fileVerifyFlag = true; $(".filename").text(fName); $(".filename").show(); $(".icon-del").show(); } }); $(".icon-del").on("click", function () { $(".icon-del").hide(); $(".filename").text('').hide(); $("#file").val(''); fileVerifyFlag = true; }); $("[type=reset]").on("click", function () { $(".filename").text('').hide(); $(".captchaImage").attr("src",urlStr + "/cos/rest/stock/captchaImage?" + Math.random()); }) </script>
总结:
我们长期使用ajax和一些高级特性,以至于我们忘了在上古时代传统的Form表单还有那么多的特性。HTML还需要好好看看。
忘了说了文件的大小和媒体类型,在IE89下没有获取,如果要获取的话需要使用IE自带的
activex诸多麻烦,就舍弃了。
参考文章:
从原型角度讲解
onsubmit
IE直接下载json文件的原因
IE支持的文件媒体类型
向mdn致谢,html、js知识点都是从上面找的
相关文章推荐
- PHP+iFrame实现页面无需刷新的异步文件上传
- iframe实现无刷新上传文件并在当前页面返回数据php处理方式
- html使用iframe实现伪异步表单,实现无刷新上传文件时遇到的问题
- iframe标签实现form表单提交(如文件上传下载)不刷新
- 关于PHP+iFrame实现页面无需刷新的异步文件上传
- 三种上传文件不刷新页面的方法讨论 iframe/FormData/FileReader
- 三种上传文件不刷新页面的方法讨论 iframe/FormData/FileReader
- 利用jquery&iframe标签实现页面无跳转的表单文件上传
- PHP+iFrame实现页面无需刷新的异步文件上传
- 三种上传文件不刷新页面的方法讨论 iframe/FormData/FileReader
- php无刷新利用iframe实现页面无刷新上传文件(1/2)
- iframe标签实现form表单提交无页面刷新(不需要js)---解析
- iframe实现无刷新上传文件
- PHP 实现页面无刷新上传文件
- php+iframe实现隐藏无刷新上传文件
- 在struts2下不刷新上传excel文件,并回调页面方法!
- 无刷新文件上传之一:传统iframe实现
- ajax(iframe)无刷新提交表单、上传文件
- ajax(iframe)无刷新提交表单、上传文件
- 使用iframe实现无刷新上传文件