2010-04-16 65 views
1

大約兩年前,我開發了一個使用GWT的Web應用程序,從那時起應用程序已經發展。在當前狀態下,它依賴於獲取單個XML文件並從中解析信息。總的來說,這很好。這個應用程序的一個要求是,它需要能夠從文件系統(文件:/// ..)以及從網絡服務器運行的傳統模式(http://..)運行。Google Web Toolkit推遲綁定問題

將文件從網絡服務器的工作原理與使用RequestBuilder對象時的預期完全相同。當從文件系統Firefox中運行應用程序時,Opera,Safari和Chrome都會按預期運行。當使用IE7或IE8從文件系統運行應用程序時,RequestBuilder.send()調用失敗,關於錯誤的信息表明由於違反了same origin policy而訪問文件時出現問題。 該應用程序在IE6中按預期工作,但不在IE7或IE8中運行。

因此,我查看了RequestBuilder.java的源代碼,並看到實際的請求正在使用XMLHttpRequest GWT對象執行。所以我查看了XMLHttpRequest.java的源代碼並找到了一些信息。

下面是代碼(在XMLHttpRequest.java開始於線83)

public static native XMLHttpRequest create() /*-{ 
    if ($wnd.XMLHttpRequest) { 
     return new XMLHttpRequest(); 
    } else { 
     try { 
     return new ActiveXObject('MSXML2.XMLHTTP.3.0'); 
     } catch (e) { 
     return new ActiveXObject("Microsoft.XMLHTTP"); 
     } 
    } 
    }-*/; 

所以基本上,如果一個XMLHttpRequest無法創建(如在IE6,因爲它是不可用)的ActiveXObject的來代替。

我讀了一點關於XMLHttpRequest的IE實現,它似乎只支持與Web服務器上的文件進行交互。

我在IE8中找到一個設置(工具 - > Internet選項 - >高級 - >安全 - >啓用本機XMLHTTP支持),當我取消選中這個框我的應用程序的作品。我認爲這是因爲我更少告訴IE不使用它們的XmlHttpRequest實現,所以GWT只使用ActiveXObject,因爲它不認爲本機XmlHttpRequest可用。

這解決了這個問題,但並不是一個長期的解決方案。

我目前可以捕獲失敗的發送請求,並驗證它是否正在嘗試使用正常的GWT從文件系統中獲取XML文件。在這種情況下,我想要做的是捕獲IE7和IE8的情況,讓他們使用ActiveXObject而不是原生的XmlHttpRequest對象。

在GWT的Google小組上發佈了一個推測解決方案(link)。看着它,我可以說它是爲舊版GWT創建的。我正在使用最新版本,並認爲這或多或少是我想要做的(使用GWT deferred binding來檢測特定的瀏覽器類型,並運行我自己的XMLHttpRequest.java實現來代替內置的GWT實現)。

這裏是我想使用

package com.mycompany.myapp.client; 

import com.google.gwt.xhr.client.XMLHttpRequest; 

public class XMLHttpRequestIE7or8 extends XMLHttpRequest 
{ 
    // commented out the "override" so that eclipse and the ant build script don't throw errors 
    //@Override 
    public static native XMLHttpRequest create() 
    /*-{ 
     try 
     { 
      return new ActiveXObject('MSXML2.XMLHTTP.3.0'); 
     } 
     catch (e) 
     { 
      return new ActiveXObject("Microsoft.XMLHTTP"); 
     } 
    }-*/; 

    // have an empty protected constructor so the ant build script doesn't throw errors 
    // the actual XMLHttpRequest constructor is empty as well so this shouldn't cause any problems 
    protected XMLHttpRequestIE7or8() 
    { 
    } 
}; 

這裏是我加入到我的模塊XML

<replace-with class="com.mycompany.myapp.client.XMLHttpRequestIE7or8"> 
    <when-type-is class="com.google.gwt.xhr.client.XMLHttpRequest"/> 
    <any> 
     <when-property-is name="user.agent" value="ie6" /> 
     <when-property-is name="user.agent" value="ie8" /> 
    </any> 
</replace-with> 

從我可以告訴這應該工作的行代碼,但我的代碼從未運行。

有沒有人有任何想法我做錯了什麼?

我不應該通過延遲綁定來做到這一點,只是使用本地JavaScript時,我捕捉失敗的情況呢?

有沒有不同的方式來解決這個問題,我沒有提到?

歡迎各位回覆。

回答

2

注意ie7不是user.agent有效值 - ie6是雙方的Internet Explorer 6和Internet Explorer 7(見UserAgent.gwt.xmluser.agent如何計算)的值。

也許這個無效值導致GWT避免使用你的代碼?

+0

感謝您的建議。我已更新我的代碼和問題與這些信息,但不幸的是,問題仍然存在 – snctln 2010-04-16 19:45:33

4

你缺少一個關鍵的事情 - 要GWT.create

建立一個呼叫的deferred binding工作,總要有人打電話GWT.create在類com.google.gwt.xhr.client.XMLHttpRequest - 只有這樣,你得到您的具體需要的實現。如果您查看RequestBuilder.java,它會直接實例化一個XMLHttpRequest對象on the first line of deSend() method。也就是說,沒有呼叫GWT.create(),因此您的IE特定的實現不會被拿起。

爲了解決這個問題,必須更換這行

XMLHttpRequest xmlHttpRequest = XMLHttpRequest.create();

XMLHttpRequest xmlHttpRequest = GWT.create(XMLHttpRequest.class);

所以,你要麼修改GWT的來源和重新編譯(YUCK! ),或者你這樣做 -

  1. 子類RequestBuilder並覆蓋sendRequest()方法。從doSend()方法
  2. 複製/粘貼一切更換一條線上面我
  3. 提到不要在你的代碼盲grep和與MyRequestBuilder

取代的RequestBuilder所有實例我想這應該解決你的問題。

+0

偉大..它適用於我:) – sunnychayen 2013-02-22 10:54:05