2014-03-25 149 views
6

我在一个FileUpload场从ExtJS的应用。我试图通过以下代码将文件加载到服务器:ExtJS的fileuplaod - 跨来源框架

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."} 

在此先感谢!

回答

3

这是一个Ext JS的错误由Uberdude在煎茶论坛确定。问题的

说明:

当您使用包含文件输入的表单的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中提取文档正文时,它将被同源策略阻止,并且传递给回调函数的响应将错误地为空responseText的。

解决办法: 1.进行上传请求时,将document.domain传递给服务器。 2.在您的服务器响应中,在您的响应文本/ html中添加document.domain。

response.setHeader( '内容 - 类型', 'text/html的'); response.write('document.domain =''+ params .__ domain +'“;'); response.write(JSON.stringify({msg:'Welcome'+ params.name})); 到Response.End( '');

详细信息:

请参考: http://www.sencha.com/forum/showthread.php?136092-Response-lost-from-upload-Ajax-request-to-iframe-if-document.domain-changed

1

这是cheftao answer的改善。

如果需要使用不同的域来工作(例如使用不同的端口本地主机),请按照下列步骤操作:

在客户端上,提交表单,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

其实,最好的解决方案是做反向代理,避免这类问题。

+0

你所说的 “反向代理” 是什么意思?你有链接的东西? – harryBundles

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