先描述一下我遇到的问题,系统里所有的表单都用ajaxSubmit来提交,成功回调success函数,普通表单都是没有问题的,但是有文件上传的表单就不行了,不会回调success,经验证会回调complete,然后就调试
发现有一个错误undefined is not a function 找到代码是这样的
var $io = $('<iframe id="' + id + '" name="' + id + '" src="' + opts.iframeSrc + '" onload="(jQuery(this).data(\'form-plugin-onload\'))()" />');
插件自己创建个iframe onload里面报错,该了一下改成onload="(function(){....})()"。
很明显这样虽然没有报错了,但是这不是没有调用success方法的原因,继续看看源码发现有个timeout参数,如果timeout有值的话就会反复执行一个方法,出发success的地方就在这里
if (opts.timeout) setTimeout(function() { timedOut = true; cb(); }, opts.timeout);
function cb() { if (cbInvoked) return; var ok = true; try { if (timedOut) throw 'timeout'; var data, doc; doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document; var isXml = opts.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc); log('isXml=' + isXml); if (!isXml && (doc.body == null || doc.body.innerHTML == '')) { if (--domCheckCount) { log('requeing onLoad callback, DOM not available'); setTimeout(cb, 250); return; } log('Could not access iframe DOM after 100 tries.'); return; } log('response detected'); cbInvoked = true; xhr.responseText = doc.body ? doc.body.innerHTML : null; xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc; xhr.getResponseHeader = function(header) { var headers = { 'content-type' : opts.dataType }; return headers[header]; }; if (opts.dataType == 'json' || opts.dataType == 'script') { var ta = doc.getElementsByTagName('textarea')[0]; if (ta) xhr.responseText = ta.value; else { var pre = doc.getElementsByTagName('pre')[0]; if (pre) xhr.responseText = pre.innerHTML; } } else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) { xhr.responseXML = toXml(xhr.responseText); } data = $.httpData(xhr, opts.dataType); } catch (e) { log('error caught:', e); ok = false; xhr.error = e; $.handleError(opts, xhr, 'error', e); } if (ok) { opts.success(data, 'success'); if (g) $.event.trigger("ajaxSuccess", [ xhr, opts ]); } if (g) $.event.trigger("ajaxComplete", [ xhr, opts ]); if (g && !--$.active) $.event.trigger("ajaxStop"); if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error'); setTimeout(function() { $io.removeData('form-plugin-onload'); $io.remove(); xhr.responseXML = null; }, 100); }
这么长的函数我没仔细看完的,然后设置了一下timeout参数
结果不行,报了个timeout异常,看看代码,发现在setTimeout的时候有一句timeOut=true,然后才执行cb()的,而cb刚开始try就有一个if(timeOut) throw "timeout",我不知到作者是什么意图,我动手改了
又碰到一个问题,$.httpData is not a function,try里面的最后一句
data = $.httpData(xhr, opts.dataType);可能是想把结果转换成dataType指定的类型,不过我没有找到$.httpData的定义,也许插件还有其他附带的js,因为我用的都是返回json所以自己统一当作json处理,终于达到目的了。
其实本人js不是很精通,只是这样做达到自己目的了,但是在网络上似乎没找到谁遇到和我一样的问题,如果有发现真实原因还请告知啊。