- 原因分析:
在使用jQuery.form.js插件进行表单异步提交时,有可能会出现连接超时(timeout)的情况。这种情况可能出现在文件上传较大或者服务器响应速度较慢的情况下。该插件内部并没有对连接超时进行完善的处理,导致浏览器一直等待,直到连接超时。
- 解决方法:
为了解决连接超时的问题,我们需要对插件进行修改,添加超时判断的代码。在jQuery.form.js文件中,可以找到form.ajaxSubmit方法。该方法中通过调用$.ajax方法进行表单数据异步提交。我们可以通过覆盖该方法来实现超时检测。
在覆盖form.ajaxSubmit方法之前,我们需要先引入jQuery插件jquery-timing.js。该插件提供了类似于setTimeout的功能,但是可以与$.ajax方法配合使用。
以下是具体步骤:
- 下载jquery-timing.js,并将其引入到html文件中。
- 修改jQuery.form.js文件,在form.ajaxSubmit方法中添加超时判断的代码。
// 覆盖form.ajaxSubmit方法
$.fn.form.prototype.ajaxSubmit = function(options) {
var container, fn1, fn2, form, i, iframe, params, ret, vals;
if (options == null) {
options = {};
}
form = this;
if (!form.length) {
return form;
}
if (typeof options === "function") {
options = {
success: options
};
}
container = options.container;
successCallback = options.success;
errorCallback = options.error;
isTimeout = options.timeout || 30000; // 超时时间,可自定义(单位:毫秒)
if (options.beforeSerialize) {
options.beforeSerialize(form);
}
params = $.param(form.serializeArray());
if (options.beforeSubmit && options.beforeSubmit(params, form) === false) {
return form;
}
iframe = $("<iframe></iframe>").attr({
src: "javascript:false;",
id: "__form__iframe__",
name: "__form__iframe__",
style: "position:absolute;left:-9999px;top:-9999px;"
}).appendTo(document.body);
ret = {
document: null,
status: 0,
readyState: "Waiting",
timeout: isTimeout
};
iframe.one("load", function() {
var contents;
ret.status = 1;
ret.readyState = "Loaded";
contents = iframe.contents();
ret.document = contents[0] ? contents[0] : contents.find("body")[0];
vals = ret.document.textContent ? ret.document.textContent : ret.document.innerText;
if (vals) {
vals = $.parseJSON(vals);
$("form").trigger('responseform', [vals]);
if (vals.status === 200) {
if (successCallback) {
return successCallback(vals.data, form, ret);
}
} else {
if (errorCallback) {
return errorCallback(vals.data, form, ret);
}
showMessage(vals.message, "warning", null, false);
}
}
clearInterval(timer);
setTimeout(function() {
return iframe.remove();
}, 50);
}).attr('data-timeout', isTimeout);
form.attr("target", "__form__iframe__").attr("method", "POST").attr("action", options.url).attr("enctype", "multipart/form-data").attr("encoding", "multipart/form-data");
iframe.attr('data-timeout', false);
i = 0;
fn1 = function() {
if (ret.status === 0) {
i++;
if (i * 1000 / 50 <= isTimeout) {
return;
}
iframe.done();
}
};
fn2 = function() {
clearInterval(timer);
$(window).unbind("unload", fn2);
};
var timer = setInterval(fn1, 50);
$(window).bind("unload", fn2);
iframe.append('<html><body><form><input type="text" name="params"></form></body></html>');
iframe.find("input[name=params]").val(params);
iframe.find('form')
.attr('target', '__form__iframe__')
.attr('method', form.attr('method'))
.attr('action', form.attr('action'))
.attr("enctype", "multipart/form-data")
.attr("encoding", "multipart/form-data")
.submit();
return form;
};
在此修改后,我们就可以在表单提交时添加超时判断了。当请求的时间超过指定的超时时间后,会进行超时处理。
- 示例说明:
以一段简单的异步提交表单代码为例:
<form id="myForm" action="submit.php" method="post">
<input type="text" name="username" />
<input type="password" name="password" />
<button type="submit">提交</button>
</form>
<script type="text/javascript">
$(function() {
$('#myForm').on('submit', function(e) {
e.preventDefault();
$(this).ajaxSubmit({
url: $(this).attr('action'),
type: 'post',
dataType: 'json',
success: function(data, status, xhr) {
alert('提交成功!');
},
error: function(xhr, status, error) {
alert('提交失败!');
},
timeout: 10000 // 超时时间为10秒
});
});
});
</script>
在这个例子中,我们给表单添加了一个提交事件,在该事件中调用了$.fn.form.prototype.ajaxSubmit方法进行表单异步提交。在options参数中,我们设置了超时时间为10秒。这样在每次表单提交时,就会进行超时判断,超过10秒就会进行超时处理。
另外,因为本例子中使用了jQuery.form.js插件和jquery-timing.js插件,所以在使用前需要先在html文件中引入相关的两个插件库。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:jQuery.form.js插件不能解决连接超时(timeout)的原因分析及解决方法 - Python技术站