我在Extjs应用程序中有一个fileupload字段。我正在尝试通过以下代码将文件加载到服务器:
var form = Ext.getCmp('ProcImpNewSugFileForm').getForm();
var fileNameStr = Ext.getCmp('ProcImpNewSugFileUpload').getValue().split("\\");
if(fileNameStr){
var filename = fileNameStr[fileNameStr.length-1];
if(form.isValid()){
form.submit({
url: '/PISRFileUploader.php',
waitMsg: 'Uploading your file...',
success: function (formPanel, action, result) {
Ext.Msg.alert('Msg',"Success: "+action.response.responseText);
},
failure: function (formPanel, action, result) {
Ext.Msg.alert('Msg',"Failure: "+action.response.responseText);
}
});
}
}
但是当我尝试上传任何文件时。该文件正被加载到服务器,但响应如下:
Failure: {success:false,message:"Blocked a frame with origin 'http://localhost' from accessing a cross-origin frame."}
预先感谢!
这是Uberdude在Sencha论坛中标识的Ext js错误。
问题描述:
[当您使用包含要上载的文件输入的表单进行Ext.Ajax.request时,或将isUpload选项手动设置为true,而不是执行适当的Ajax请求时,Ext以标准HTML方式将表单动态提交给产生隐藏。然后,从iframe中读取json响应主体,以创建伪造的Ajax响应。如果发出上传Ajax请求的页面更改了其document.domain属性,例如, home.example.com上的页面包含来自static.example.com的资源,该资源希望使用javascript进行操作而不会违反浏览器的同源策略,因此都将其document.domain设置为“ example.com”。如果home.example.com然后向home.example.com服务器上的URL发出上载Ajax请求,则写入响应的iframe的document.domain将为“ home.example.com”。因此,当home.example.com页面上Ajax.request中的ExtJS代码尝试从iframe中提取文档主体时,它将被same-origin-policy阻止,并且传递给回调函数的响应将错误地为空responseText。
变通:1.发出上传请求时,将document.domain传递到服务器。2.在服务器响应中,在响应text / html中添加document.domain。
response.setHeader('Content-Type','text / html');response.write('document.domain =“'+ params .__ domain +'”;');response.write(JSON.stringify({msg:'Welcome'+ params.name}));response.end('');
Detail:
[在Wilk的答案中添加其他评论。
如果主机和目的地在不同的端口上,请使用以下解决方案。
在index.html
文件中,在标题下使用以下行:
<script type=text/javascript>document.domain =document.domain;</script>
以及您的响应以及标题Content-Type:'text/html'
和响应
'<html><head><script type=text/javascript>document.domain =document.domain;</script></head><body>{success: true}</body></html>'
这里成功消息是硬编码的,您可以根据输入使用任何自定义消息。
谢谢,Santrupta
这是cheftao answer的改进。
如果您需要使用其他域(例如,具有不同端口的localhost),请按照以下步骤操作:
在客户端,在提交表单之前,先单击renew the document domain,然后将其与表单数据一起提交:
document.domain = document.domain;
myForm.submit({
params: {
domain: document.domain
},
...
});
在服务器端,使用内容类型text / html并使用以下字符串(此示例通过ExpressJS完成):
var domain = req.body.domain,
script = '<script type="text/javascript">document.domain = "' + domain + '";</script>',
body = '<body>' + JSON.stringify({success: true}) + '</body>';
res.send('<html><head>' + script + '</head>' + body + '</html>');
更新:19/05/2016
实际上,最好的解决方案是进行反向代理,以避免此类问题。