我在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."}
提前致谢!
答案 0 :(得分:4)
这是Uberdude在Sencha论坛中发现的一个Ext js bug。
问题描述:
使用包含要上载的文件输入的表单创建Ext.Ajax.request时,或者手动将isUpload选项设置为true,而不是执行正确的Ajax请求Ext以标准HTML方式将表单提交给动态生成隐藏。然后从iframe中读出json响应主体以创建伪造的Ajax响应。如果发出上传Ajax请求的页面已经改变了其document.domain属性,例如,则会出现问题。 home.example.com上的一个页面包含来自static.example.com的资源,它希望用javascript操作而不违反浏览器的同源政策,所以都将他们的document.domain设置为"示例.COM&#34 ;.如果home.example.com然后向home.example.com服务器上的URL发送Ajax请求,则写入响应的iframe将其document.domain作为" home.example.com&#34 ;。因此,当home.example.com页面上的Ajax.request中的ExtJS代码尝试从iframe中提取文档正文时,它将被同源策略阻止,并且传递给回调函数的响应将错误地为空responseText的。
解决方法: 1.在发出上传请求时将document.domain传递给服务器。 2.在服务器响应中,在响应文本/ 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('&#39);
明细:
答案 1 :(得分:1)
这是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>');
更新:2016年5月19日
实际上,最好的解决方案是进行反向代理,避免出现这种问题。
答案 2 :(得分:1)
在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