GWT 和 Sencha GXT:表单面板结果失败



TL/DR:如何可靠地通过FormPanel加载XML响应?


我们在GWT中有一个Web应用程序,在大多数UI中使用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 包装器中)。我尝试了以下方法:

  1. 我最初使用了Content-Type: text/html(本地PHP测试脚本中的监督,生产代码中的错误)。在Firefox和Chrome中工作,但在IE(9)中不起作用,在IE(9)中,XML在IFrame中作为XML加载。
  2. Content-Type: application/xml哪个是有效载荷的正确选择。现在它在任何地方都不起作用,因为我们现在得到了最初只有IE在Chrome和FF中表现出的行为。
  3. Content-Type: application/octet-stream :不是一个好主意,它只是下载文件。
  4. Content-Type: text/plain :我希望这总是会触发 HTML/body 包装,它确实如此,但它也将所有内容包装在一个 pre 元素中,所以它现在到处都失败了,但至少是可靠的。伟大。

经过一番挖掘,我发现显然GXT FormPanel使用与GWT相同的FormPanelImpl,因此两者的结果无论如何都是相同的。GWT的文件说(Sencha明智地隐瞒了):

后端服务器应该以'text/html'的内容类型进行响应,这意味着返回的文本将被视为HTML。如果服务器指定了任何其他内容类型,则在 onFormSubmit 事件中发送的结果 html 在浏览器中将是不可预测的,并且 FormHandler.onSubmitComplete(FormSubmitCompleteEvent) 事件可能根本不会触发。

但是,即使使用发送text/html如果有效负载是 XML,则跨浏览器的行为也是不可预测的。

有没有通用的解决方案?还是我错过了一些非常琐碎的东西(我现在只看了三天的 GWT)?

编辑:我尝试在文件内容前面<html><body>,因此即使IE也会在IFrame中有一个正文。嗯,它确实如此,但它也导致了一个非常非常奇怪的innerHTML开始:

<?XML:NAMESPACE PREFIX = [default] ...

可以理解的是,XML 解析器会阻塞。

我的猜测是,一般来说,将 XML 包装在 HTML 上下文中而不执行任何特殊字符转义是不可靠的。我希望它至少会失败,像这样的XML文档

<a>
  <b>
    <html>
    </html>
  </b>
</a>

我们采取的方法是只发回一条小的"OK"消息,然后使用单独的请求从服务器获取(缓存的)内容。

或者,可能可以执行HTML编码/解码(或Base64,...

解决方法是覆盖类com.google.gwt.dom.client.Element.FormPanelImpl中的方法getContent

代码更改是使用textContent而不是innerHTML

public native String getContents(Element iframe) /*-{
  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.textContent;
  } catch (e) {
    return null;
  }
}-*/;

我不知道这是否是GWT错误。

乔迪。

相关内容

  • 没有找到相关文章

最新更新