1

約 2 年前に GWT を使用して Web アプリを開発しました。それ以来、アプリケーションは進化し​​てきました。現在の状態では、単一の XML ファイルを取得し、そこから情報を解析することに依存しています。全体として、これはうまく機能します。このアプリの要件は、ファイルシステム (file:///..) から実行できる必要があることと、Web サーバーから実行する従来のモデル ( http://.. .)から実行できる必要があることです。

このファイルを Web サーバーから取得すると、RequestBuilderオブジェクトを使用して期待どおりに動作します。ファイルシステム Firefox、Opera、Safari、および Chrome からアプリを実行すると、すべて期待どおりに動作します。IE7 または IE8 を使用してファイル システムからアプリを実行すると、RequestBuilder.send()の呼び出しが失敗し、エラーに関する情報は、同じオリジン ポリシーに違反しているため、ファイルへのアクセスに問題があることを示唆しています。アプリは 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 で設定を見つけました ([ツール] -> [インターネット オプション] -> [詳細設定] -> [セキュリティ] -> [ネイティブ XMLHTTP サポートを有効にする])。このボックスのチェックを外すと、アプリが動作します。これは、IE に XmlHttpRequest の実装を使用しないように指示することが少ないためだと思います。GWT は、ネイティブの XmlHttpRequest が利用可能であるとは考えていないため、ActiveXObject を使用するだけです。

これで問題は解決しますが、長期的な解決にはなりません。

現在、失敗した送信リクエストをキャッチし、通常の GWT を使用してファイル システムから XML ファイルをフェッチしようとしていたことを確認できます。この場合にやりたいことは、IE7 と IE8 のケースをキャッチして、ネイティブの XmlHttpRequest オブジェクトの代わりに ActiveXObject を使用させることです。

この問題の解決策と思われる GWT の Google グループに投稿がありました (リンク)。これを見ると、古いバージョンの GWT 用に作成されたものであることがわかります。私は最新のリリースを使用しており、これが多かれ少なかれやりたいことだと思います ( GWT 遅延バインディングを使用して特定のブラウザーの種類を検出し、組み込みの GWT 実装の代わりに XMLHttpRequest.java の独自の実装を実行します)。

これが私が使用しようとしているコードです

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 を使用する必要がありますか?

私が言及していないこの問題に取り組む別の方法はありますか?

すべての返信を歓迎します。

4

2 に答える 2

4

あなたは1つの重要なことを見逃しています - への呼び出しGWT.create

遅延バインディングを機能させるには、誰かがクラスで GWT.create を呼び出す必要があります。そうして初めてcom.google.gwt.xhr.client.XMLHttpRequest、ニーズに固有の実装が得られます。RequestBuilder.java を見ると、deSend() メソッドの最初の行で XMLHttpRequest オブジェクトを直接インスタンス化しています。つまり、 への呼び出しがないGWT.create()ため、IE 固有の実装が取得されません。

この問題を解決するには、この行を置き換える必要があります

XMLHttpRequest xmlHttpRequest = XMLHttpRequest.create();

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

したがって、GWT のソースを変更して再コンパイルするか (YUCK!)、次のようなことを行います -

  1. sendRequest RequestBuilder() メソッドをサブクラス化してオーバーライドします。
  2. doSend()メソッドからすべてをコピーして貼り付けますが、上記の1行を置き換えます
  3. コードでブラインドグレップを実行し、すべてのインスタンスをに置き換えRequestBuilderますMyRequestBuilder

私はそれがあなたの問題を解決するはずだと思います。

于 2010-04-17T15:37:00.810 に答える
2

ie7は有効な値ではないことに注意してくださいuser.agent-ie6は Internet Explorer 6 と Internet Explorer 7 の両方の値です ( の計算方法については、 UserAgent.gwt.xmlを参照してください)。user.agent

この無効な値が原因で、GWT がコードをまったく使用しないようになっているのではないでしょうか?

于 2010-04-16T19:24:53.733 に答える