TL/DR: Как надежно загрузить ответ XML через FormPanel
?GWT и Sencha GXT: результат FormPanel не удается
У нас есть веб-приложение в GWT с использованием Sencha GXT для большей части пользовательского интерфейса. Мы используем GXT FormPanel
для загрузки файла на серверный скрипт (который просто перекликается с содержимым файла), чтобы получить содержимое локального файла в JS. В конце концов это можно сделать с помощью FileReader, но, очевидно, не в браузерах, которые этого не поддерживают.
FormPanel
представляет свою форму и загружает результат в скрытой IFrame, из которой содержимое извлекаются с помощью следующего фрагмента кода (от 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;
}
мы загружаем XML-файл, который, как и проблематичной линия
return iframe.contentWindow.document.body.innerHTML;
, поскольку XML загружается как XML (и, таким образом, не встраивается в HTML-обертку) в нескольких случаях. Я пробовал следующее:
- Первоначально я использовал
Content-Type: text/html
(надзор в локальном тестовом сценарии PHP, ошибка с моей стороны в производственном коде). Работал в Firefox и Chrome, но не в IE (9), где XML был загружен как XML в IFrame. Content-Type: application/xml
, который был бы правильным для полезной нагрузки. Теперь это нигде не работает, потому что теперь мы получаем поведение, которое изначально только IE проявлялось в Chrome и FF.Content-Type: application/octet-stream
: Неплохая идея, она просто загружает файл.Content-Type: text/plain
: Я надеялся, что это всегда вызовет обертывание HTML/body, но оно также обертывает все в элементеpre
, поэтому теперь он выходит из строя повсюду, но, по крайней мере, надежно. Отлично.
Через некоторое рытье я узнал, что по-видимому, GXT FormPanel
использует тот же FormPanelImpl
из GWT, так что результаты одинаковы для обоих в любом случае. И документация GWT говорит (что Сенч мудро удержан):
Фоновый сервер ожидает реакция с типом содержимого
'text/html'
, а это означает, что текст возвращается будет рассматриваться как HTML. Если какой-либо другой тип содержимого указан сервером, то результат html, отправленный в событииonFormSubmit
, будет непредсказуемым в разных браузерах, и событиеFormHandler.onSubmitComplete(FormSubmitCompleteEvent)
может вообще не срабатывать.
Однако, даже при отправке text/html
поведение непредсказуемо в браузерах, если полезная нагрузка представляет собой XML.
Есть ли общее решение? Или я пропустил что-то ужасно тривиальное (я смотрю на GWT всего три дня)?
EDIT: Я попытался добавить <html><body>
к содержимому файла, поэтому даже IE будет иметь тело в IFrame.Ну, это так, но это также привело к очень, очень странный innerHTML
начиная с:
<?XML:NAMESPACE PREFIX = [default] ...
которую XML-парсер по понятным причинам давится.
Любое кодирование по-прежнему создает некоторую боль в настоящее время по двум причинам: (a) Это GWT, поэтому в значительной степени просто Java-язык без Java-стандартной библиотеки, что означает, что большинство способов декодирования Base64 не будут выполняться. И (b) Кодирование выполняется на уровне байтов, что требует от меня выяснить кодировку (надеюсь, UTF-8, но вы никогда не узнаете) впоследствии. Поскольку GWT не имеет никаких положений, связанных с этим, я все еще в недоумении, как с этим справиться. По крайней мере, я бы сказал, что это проблема документации GWT (как если бы этого было недостаточно). – Joey
@Joey: Я согласен, документация (GWT) FormPanel может отсутствовать в нескольких деталях (GXT еще один). Мы нашли множество преимуществ в использовании отдельного запроса: он позволяет упростить повторную загрузку, параллельную загрузку с помощью диспетчера загрузки, улучшенная безопасность (с сервлетом, который отображает все, что вы отправляете, может быть опасным), ... –
Я решил это сейчас используя этот метод в [этом ответе] (http://stackoverflow.com/a/6491785/73070). По сути, это замена специальных символов объектами HTML и декодирование на стороне клиента. Единственная проблема, с которой я столкнулся сейчас, - случайные исключения в Chrome, но * только * в режиме размещения, но это еще один вопрос: ;-). Загрузка загруженного файла по отдельности была бы слишком переработана здесь прямо сейчас, и я даже не знаю, есть ли у нас способы записи файлов, где он размещен из эхо-скрипта, поэтому я решил это сейчас. – Joey