TL/DR: How to load an XML response via FormPanel
reliably?
We have a web application in GWT using Sencha GXT for most of the UI. We use a GXT FormPanel
to upload a file to a server-side script (which just echoes the file's contents) to get a local file's contents in JS. Eventually this can be done with FileReader, but obviously not in browsers that don't support that.
The FormPanel
submits its form and loads the result in a hidden IFrame from which the contents are extracted with the following snippet (from 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;
}
We're loading an XML file that way and the problematic line is
return iframe.contentWindow.document.body.innerHTML;
because the XML is loaded as XML (and thus not embedded in a HTML wrapper) in a few cases. I tried the following:
- I used
Content-Type: text/html
originally (oversight in the local PHP test script, error on my part in the production code). Worked in Firefox and Chrome but not in IE (9) where the XML was loaded as XML in the IFrame instead. Content-Type: application/xml
which would be the correct one for the payload. Now it doesn't work anywhere because we now get the behaviour that originally only IE exhibited in Chrome and FF too.Content-Type: application/octet-stream
: Not a good idea, it just downloads the file.Content-Type: text/plain
: I was hoping this would always trigger the HTML/body wrapping and it does, but it also wraps everything in apre
element so it now fails everywhere, but that at least reliably. Great.
After a little digging I found out that apparently the GXT FormPanel
uses the same FormPanelImpl
from GWT so results are identical for both anyway. And GWT's documentation says (which Sencha wisely withheld):
The back-end server is expected to respond with a content-type of
'text/html'
, meaning that the text returned will be treated as HTML. If any other content-type is specified by the server, then the result html sent in theonFormSubmit
event will be unpredictable across browsers, and theFormHandler.onSubmitComplete(FormSubmitCompleteEvent)
event may not fire at all.
However, even with sending text/html
the behaviour is unpredictable across browsers if the payload is XML.
Is there a general solution to this? Or am I missing something terribly trivial (I'm looking at GWT for just three days now)?
EDIT: I tried prepending <html><body>
to the file contents so even IE would have a body in the IFrame. Well, it did, but it also resulted in a very, very strange innerHTML
starting with:
<?XML:NAMESPACE PREFIX = [default] ...
which the XML parser understandably chokes on.