[Sorry in advance for the lengthy post, I just posted this question
over on stack overflow and copy/pasted the question here for more
visibilty, so this is formatted with markup and all links referenced
are at the bottom of the post]

I developed a web app using GWT about 2 years ago, since then the
application has evolved.  In its current state it relies on fetching a
single XML file and parsing the information from it.  Overall this
works great.  A requirement of this app is that it needs to be able to
be ran from the filesystem (file:///..) as well as the traditional
model of running from a webserver (http://...)

Fetching this file from a webserver works exactly as expected using a
[RequestBuilder][1] object.  When running the app from the filesystem
Firefox, Opera, Safari, and Chrome all behave as expected.  When
running the app from the filesystem using IE7 or IE8 the
[RequestBuilder.send()][2] call fails, the information about the error
suggests that there is a problem accessing the file due to violating
the [same origin policy][3].
The app worked as expected in IE6 but not in IE7 or IE8.

So I looked at the source code of [RequestBuilder.java][4] and saw
that the actual request was being executed with an XMLHttpRequest GWT
object.  So I looked at the source code for [XMLHttpRequest.java][5]
and found out some information.

Here is the code (starts at line 83 in 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");
          }
        }
      }-*/;

So basically if an XMLHttpRequest cannot be created (like in IE6
because it is not available) an ActiveXObject is used instead.

I read up a little bit more on the IE implementation of
XMLHttpRequest, and it appears that it is only supported for
interacting with files on a webserver.

I found a setting in IE8 (Tools->Internet Options->Advanced->Security-
>Enable native XMLHTTP support), when I uncheck this box my app
works.  I assume this is because I am more of less telling IE to not
use their implementation of XmlHttpRequest, so GWT just uses an
ActiveXObject because it doesn't think the native XmlHttpRequest is
available.

This fixes the problem, but is hardly a long term solution.

I can currently catch a failed send request and verify that it was
trying to fetch the XML file from the filesystem using normal GWT.
What I would like to do in this case is catch the IE7 and IE8 case and
have them use a ActiveXObject instead of a native XmlHttpRequest
object.

There was a posting on the GWT google group that had a supposed
solution for this problem ([link][6]).  Looking at it I can tell that
it was created for an older version of GWT.  I am using the latest
release and think that this is more or less what I would like to do
(use [GWT deferred binding][7] to detect a specific browser type and
run my own implementation of XMLHttpRequest.java in place of the built
in GWT implementation).

Here is the code that I am trying to use

    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()
        {
        }
    };

And here are the lines that I added to my module 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="ie7" />
            <when-property-is name="user.agent" value="ie8" />
        </any>
    </replace-with>

>From what I can tell this should work, but my code never runs.

Does anyone have any idea of what I am doing wrong?

Should I not do this via deferred binding and just use native
javascript when I catch the fail case instead?

Is there a different way of approaching this problem that I have not
mentioned?

All replies are welcome.

  [1]: 
http://google-web-toolkit.googlecode.com/svn/javadoc/2.0/com/google/gwt/http/client/RequestBuilder.html
  [2]: 
http://google-web-toolkit.googlecode.com/svn/javadoc/2.0/com/google/gwt/http/client/RequestBuilder.html#send%28%29
  [3]: http://en.wikipedia.org/wiki/Same_origin_policy
  [4]: 
http://code.google.com/p/google-web-toolkit/source/browse/releases/2.0/user/src/com/google/gwt/http/client/RequestBuilder.java
  [5]: 
http://code.google.com/p/google-web-toolkit/source/browse/releases/2.0/user/src/com/google/gwt/xhr/client/XMLHttpRequest.java
  [6]: 
http://groups.google.com/group/google-web-toolkit/browse_thread/thread/3a3935fe1534a486
  [7]: 
http://code.google.com/webtoolkit/doc/latest/DevGuideCodingBasicsDeferred.html

-- 
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-web-toolkit?hl=en.

Reply via email to