基于iframe的异步表单提交与图片上传兼容方案

作者:闭包旅人时间:2026-10-24 21:44:27浏览:263

本文介绍一种基于iframe的异步表单提交技术,旨在解决早期浏览器对Ajax支持不足的问题。通过动态创建隐藏表单与iframe,利用form的target属性实现无刷新提交,并支持图片上传。该方法兼容多浏览器,可模拟Ajax交互,适用于需要兼容旧版浏览器的场景。

异步表单提交技术概述

前言:


乍看标题功能繁多,实则核心仅为一项:异步表单提交。该方案在异步提交基础上扩展了图片上传功能,并模拟了Ajax技术(早期多浏览器兼容Ajax即采用此方式)。此处仅作技术回顾与探讨,阅读需具备一定JavaScript基础。


注意事项:

此方法源自bBank框架,现提取为通用方法进行讲解。


bBank框架介绍:http://www.cnblogs.com/bruceli/archive/2010/04/15/bBank.html


提及bBank是因为该方法依赖其部分功能:数组判断、字符串转标准DOM对象(详见前文)、移除自身方法及CSS选择器。读者可自行编写替代方法,或直接使用bBank方法(可下载源码查看)。


b$.type.isArray(args):判断参数是否为数组。


b$.parseDom(strs):将字符串直接转换为标准DOM对象。


b$('#bBankAsynFormSubmit_form_1b').removeSelf():移除指定元素自身。


b$():CSS选择器封装。


原理:

基于iframe的异步提交原理

核心原理是利用iframe实现异步。在页面中嵌入一个隐藏的iframe,将表单的target属性指向该iframe。提交表单时,内容在iframe内加载,页面其他部分保持无刷新状态。


原理简单:iframe作为显示载体,若提交页面有返回值,该值将成为iframe body的内容。通过读取iframe body内容即可获取结果,这与Ajax类似,是早期实现异步通信的方法。


Ajax基于事件触发,模拟Ajax也需触发事件。只需利用iframe的onload加载完成事件即可实现。


实现:

核心代码实现与解析

代码示例:


代码如下:

 
var asyn = {
formSubmit: function (args, action, func) {
this.clearContext();
this.callBack = null;
var subArr = [];
var subArrT = [];
if (b$.type.isArray(args)) {
subArr = args;
} else {
var tag = args.tagName.toLowerCase();
if (tag == "form") { for (var i = 0, num = args.childNodes.length; i < num; i++) { subArr.push(args.childNodes[i]); } }
else { subArr = [args]; }
} 
//create asyn form and ifroma
var objForm = document.createElement("form");
objForm.action = action;
objForm.target = "bBankAsynFormSubmit_iframe_1b";
objForm.encoding = "multipart/form-data";
objForm.method = "post";
objForm.id = "bBankAsynFormSubmit_form_1b";
objForm.style.display = "none";
var objIframe = b$.parseDom('<iframe id="bBankAsynFormSubmit_iframe_1b" name="bBankAsynFormSubmit_iframe_1b" src="about:blank" style="display:none;" onload="javascript:setTimeout(\'asyn.complete()\',100)"></iframe>')[0];
//add submit value in form
for (var i = 0, num = subArr.length; i < num; i++) {
if (!subArr[i].name && subArr[i].nodeType == 1 && subArr[i].tagName.toLowerCase() == "input") subArr[i].name = "bBankAsynFormSubmit_input_1b_" + i;
var input = subArr[i].cloneNode(true);
subArrT.push(input);
subArr[i].parentNode.replaceChild(input, subArr[i]);
objForm.appendChild(subArr[i]);
} 
//submit
document.body.appendChild(objIframe);
document.body.appendChild(objForm);
objForm.submit();
//dispose
for (var i = 0, num = subArrT.length; i < num; i++) { subArrT[i].parentNode.replaceChild(subArr[i], subArrT[i]); }
if (func) this.callBack = func;
}, 
complete: function () {
var responseText = "";
try {
var objIframe = document.getElementById("bBankAsynFormSubmit_iframe_1b");
if (objIframe.contentWindow) { responseText = objIframe.contentWindow.document.body.innerHTML; }
else { responseText = objIframe.contentDocument.document.body.innerHTML; }
} catch (err) { }
this.clearContext();
if (this.callBack) this.callBack(responseText);
}, 
clearContext: function () {
if (b$('#bBankAsynFormSubmit_form_1b')) b$('#bBankAsynFormSubmit_form_1b').removeSelf();
if (b$('#bBankAsynFormSubmit_iframe_1b')) b$('#bBankAsynFormSubmit_iframe_1b').removeSelf();
}, 
callBack: null
}; 

  简单讲解:

主要难点在于iframe的多浏览器兼容,但此处无需过度纠结,交由浏览器解析即可,代码中使用了字符串转DOM对象来处理。


首先创建隐藏的form和iframe,将原表单内容复制到隐藏表单中并提交。提交完成后,移除创建的表单和iframe。


使用方法与示例

使用方法:


asyn.formSubmit(args, action [, func])。args可为form表单、input元素或input数组;action为提交URL;func为回调函数。


示例:asyn.formSubmit(inputArr, 'xxx.aspx', function(d){


alert(d);


});

END


至此结束。推荐一个本人编写的JS框架,上述方法已集成其中。


使用示例:


代码如下:

 
b$.asyn.formSubmit(inputArr, 'xxx.aspx', function(d){
alert(d);
}); 
作者最新文章