因为要使用表单实现跨域上传文件,但是发现在6.7居然不行,需要自己手动去创建​​FormData​​对象来提交,这比较奇怪。经过分析源代码,终于找到了这个bug,主要代码如下:

...
if (Ext.feature.has.XHR2 && request.xhr2) {
delete request.form;
var formData = request.data = new FormData(form);
if (request.params) {
Ext.iterate(request.params, function(name, value) {
if (Ext.isArray(value)) {
Ext.each(value, function(v) {
formData.append(name, v);
});
} else {
formData.append(name, value);
}
});
delete request.params;
}
}
return Ext.Ajax.request(request);

以上代码是​​Ext.form.Panel​​​的​​beforeAjaxSubmit​​​代码片段,主要错误是在创建​​FormData​​​的时候把值赋值给了​​data​​​属性,而不是​​rawData​​​属性,这导致了在​​Ext.Ajax​​​的​​setOptions​​方法中把表单值都忽略了,从而什么也没提交。

通过重写​​Ext.form.Panel​​​的​​beforeAjaxSubmit​​方法,就可使用以下代码轻松的跨域上传文件了:

view.submit({
xhr2:true,
headers:{
"Content-Type": null
},
method: 'POST',
submitEmptyText: false,
url: URI.get(CFG.organizationUnit.id === 1 ? 'shareProduct': 'product', 'import'),
success: me.onSubmitSuccess,
failure: me.onSubmitFailure,
scope: me
});

代码中,​​xhr2​​​是必须的,从刚才的代码也可以看到,只有当该值为true的时候,才会使用​​FormData​​​对象来提交数据,而这是使用​​Ajax​​​来上传文件的常用方式。另外一个要注意的地方就是要将​​Content-Type​​​设置为​​null​​​,以便自动生成正确的​​Content-Type​​,不然提交也不会成功。