2012-06-29 25 views
3

TL/DR:如何通過FormPanel可靠地加載XML響應?GWT和Sencha GXT:FormPanel結果失敗


我們在GWT中使用Sencha GXT的Web應用程序用於大多數UI。我們使用GXT FormPanel將文件上傳到服務器端腳本(它只是迴應文件內容)以獲取JS中的本地文件內容。最終這可以通過FileReader完成,但顯然不適用於不支持該功能的瀏覽器。

FormPanel提交其形式,並且將結果從其中的內容與下面的代碼片段中提取隱藏的iframe(從FormPanelImpl.class):

try { 
    // Make sure the iframe's window & document are loaded. 
    if (!iframe.contentWindow || !iframe.contentWindow.document) 
    return null; 

    // Get the body's entire inner HTML. 
    return iframe.contentWindow.document.body.innerHTML; 
} catch (e) { 
    return null; 
} 

我們加載XML文件的方式和有問題的行是

return iframe.contentWindow.document.body.innerHTML; 

因爲XML在少數情況下作爲XML加載(因此不嵌入HTML包裝器中)。我試過如下:

  1. 我用Content-Type: text/html最初(監督當地PHP測試腳本,錯誤在我的生產代碼的一部分)。在Firefox和Chrome中工作,但不在IE(9)中,而是在IFrame中將XML作爲XML加載。
  2. Content-Type: application/xml這對於有效載荷來說是正確的。現在它無法在任何地方工作,因爲我們現在得到的只是IE和FF中展示的行爲。
  3. Content-Type: application/octet-stream:不是一個好主意,它只是下載文件。
  4. Content-Type: text/plain:我希望這將始終觸發HTML /正文換行,但它也將所有內容封裝在pre元素中,因此它現在無處不在,但至少可靠。大。

後小挖我發現,顯然GXT FormPanel從GWT使用相同FormPanelImpl這樣的結果對於兩個反正是相同的。和GWT的文件說,(這煎茶明智地省略):

後端服務器預計將與內容型'text/html'迴應,這意味着返回的文本將作爲HTML處理。如果服務器指定了其他任何內容類型,則在onFormSubmit事件中發送的結果html在瀏覽器中將不可預知,並且FormHandler.onSubmitComplete(FormSubmitCompleteEvent)事件可能根本不會觸發。

但是,即使發送text/html,如果有效負載是XML,跨瀏覽器的行爲也是不可預知的。

有沒有一個通用的解決方案呢?或者我錯過了一些非常微不足道的東西(我現在正在看GWT三天)?

編輯:我試着預先到文件的內容,所以即使IE將在IFrame中有一個正文。那麼,它做到了,但它也造成了一個非常,非常奇怪innerHTML開始:

<?XML:NAMESPACE PREFIX = [default] ... 

其XML解析器可以理解的扼流圈。

回答

1

我的猜測是,通常情況下,將XML包裝在HTML上下文中而不執行任何特殊字符轉義,並不可靠。我希望它至少與像

<a> 
    <b> 
    <html> 
    </html> 
    </b> 
</a> 

我們採取了是隻發回一個小的「OK」消息,該方法的XML文檔失敗,然後使用一個單獨的請求來獲取從(緩存)的內容服務器。

可替代地,它很可能是能夠進行的HTML編碼/解碼(或Base64,...)

+0

任何編碼仍然會產生一些痛苦,目前有兩個原因:(a)它是GWT,所以幾乎只是沒有Java的Java-the-standard-library,這意味着大多數Base64解碼方式都不能運行。和(b)編碼是在字節級完成的,這需要我在之後計算出編碼(希望是UTF-8,但你永遠不會知道)。由於GWT沒有處理這個問題的條款,所以我仍然不知如何處理它。至少我還是會說這是一個GWT文檔問題(好像沒有足夠的)。 – Joey

+0

@Joey:我同意,(GWT)FormPanel文檔可能會在這裏丟失一些細節(GXT更多)。我們在使用單獨的請求時發現了許多優點:它允許更輕鬆的重新下載,使用下載管理器進行並行下載,提高安全性(具有反映您發送的所有內容的servlet可能是危險的),... –

+0

我現在解決了它通過使用[這個答案]中的方法(http://stackoverflow.com/a/6491785/73070)。這實質上是用HTML實體替代特殊字符並在客戶端進行解碼。我現在遇到的唯一問題是Chrome中的隨機例外,但*僅*在託管模式下,但那是另一個問題;-)。單獨下載上傳的文件現在會過多地重新工作,我甚至不知道我們是否有辦法將文件從echo腳本託管到文件中,因此現在我排除了它。 – Joey

0

一種解決方法是要覆蓋的方法getContents在類com.google.gwt.dom .client.Element.FormPanelImpl

代碼更改爲使用textContent而不是innerHTML。我不知道這是不是一個GWT錯誤。

Jordi。

+0

而我將如何獲得'FormPanel'來使用我的派生實現? – Joey

+0

我打開了一張票http://code.google.com/p/google-web-toolkit/issues/detail?id=7535,但顯然他們不會修復它導致FormPanel的文檔說它只能返回文本/ HTML。 –

+0

新FormPanelImpl(){ \t \t \t \t \t公共本地字符串getContents(com.google.gwt.dom.client.Element IFRAME)/ * - {} JSCode - * /; \t \t \t \t \t}; –