Google Web Toolkit отложил проблему привязки - PullRequest
1 голос
/ 16 апреля 2010

Я разработал веб-приложение с использованием GWT около 2 лет назад, с тех пор приложение развивалось. В своем текущем состоянии он полагается на выборку одного файла XML и анализ информации из него. В целом это прекрасно работает. Требование этого приложения заключается в том, что его необходимо запускать из файловой системы (file: /// ..), а также из традиционной модели запуска с веб-сервера ( http: //..*1002). *.)

Извлечение этого файла с веб-сервера работает точно так же, как и ожидалось, с использованием объекта RequestBuilder . При запуске приложения из файловой системы Firefox, Opera, Safari и Chrome ведут себя должным образом. При запуске приложения из файловой системы с использованием IE7 или IE8 происходит сбой вызова RequestBuilder.send () , информация об ошибке указывает на то, что существует проблема с доступом к файлу из-за нарушения политики того же источника . Приложение работает должным образом в IE6, но не в IE7 или IE8.

Итак, я посмотрел на исходный код RequestBuilder.java и увидел, что фактический запрос выполняется с объектом GWT XMLHttpRequest. Поэтому я посмотрел на исходный код XMLHttpRequest.java и нашел некоторую информацию.

Вот код (начинается со строки 83 в XMLHttpRequest.java)

  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, и кажется, что он поддерживается только для взаимодействия с файлами на веб-сервере.

Я обнаружил настройку в IE8 (Сервис-> Свойства обозревателя-> Дополнительно-> Безопасность-> Включить поддержку собственного XMLHTTP), когда я снял этот флажок, мое приложение работает. Я предполагаю, что это потому, что я все меньше и меньше говорю IE не использовать их реализацию XmlHttpRequest, поэтому GWT просто использует ActiveXObject, потому что не думает, что собственный XmlHttpRequest доступен.

Это решает проблему, но вряд ли является долгосрочным решением.

В настоящее время я могу отловить неудавшийся запрос на отправку и убедиться, что он пытался извлечь файл XML из файловой системы, используя обычный GWT. В этом случае я хотел бы перехватить IE7 и IE8, чтобы они использовали ActiveXObject вместо собственного объекта XmlHttpRequest.

В группе Google GWT было опубликовано сообщение о предполагаемом решении этой проблемы ( ссылка ). Глядя на это, я могу сказать, что он был создан для более старой версии GWT. Я использую последнюю версию и думаю, что это более или менее то, что я хотел бы сделать (используйте GWT отложенное связывание , чтобы обнаружить определенный тип браузера и запустить мою собственную реализацию 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 ]

4 голосов
/ 17 апреля 2010

Вам не хватает одной ключевой вещи - звонка на GWT.create

Чтобы отложенное связывание заработало, кто-то должен вызвать GWT.create для класса com.google.gwt.xhr.client.XMLHttpRequest - только тогда вы получите реализацию, соответствующую вашим потребностям. Если вы посмотрите на RequestBuilder.java, он непосредственно создает экземпляр объекта XMLHttpRequest в первой строке метода deSend () . То есть, нет вызова GWT.create(), и, следовательно, ваша специфичная для IE реализация не воспринимается.

Чтобы решить проблему, вы должны заменить эту строку

XMLHttpRequest xmlHttpRequest = XMLHttpRequest.create();

с

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

Итак, вы либо модифицируете источник GWT и перекомпилируете (YUCK!), Либо делаете что-то вроде этого -

  1. Подкласс RequestBuilder и переопределить метод sendRequest ().
  2. Копирование / вставка всего из doSend() метода НО замените одну строку, которую я упомянул выше
  3. Сделайте слепой grep в вашем коде и замените все экземпляры RequestBuilder на MyRequestBuilder

Полагаю, это должно решить вашу проблему.

2 голосов
/ 16 апреля 2010

Обратите внимание, что ie7 не является допустимым значением для user.agent - ie6 является значением как для Internet Explorer 6, так и для Internet Explorer 7 (см. UserAgent.gwt.xml , чтобы узнать, как user.agent вычисляется).

Возможно, это неверное значение заставляет GWT вообще не использовать ваш код?

...