2014-03-25 143 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