您的位置:首页 > 其它

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知识点都是从上面找的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: