GWT和Sencha GXT:FormPanel结果失败

时间:2012-06-29 10:50:39

标签: xml gwt gxt formpanel

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


我们在GWT中使用Sencha GXT在大多数UI中都有一个Web应用程序。我们使用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)中,而是在IFrame中将XML作为XML加载。
  2. Content-Type: application/xml这对于有效载荷来说是正确的。现在它在任何地方都无法工作,因为我们现在得到的行为原本只有IE在Chrome和FF中展示过。
  3. Content-Type: application/octet-stream:不是一个好主意,它只是下载文件。
  4. Content-Type: text/plain:我希望这总是会触发HTML / body包装,但它确实包含了pre元素中的所有内容,所以它现在无处可去,但至少可靠。大。
  5. 经过一番挖掘后,我发现显然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解析器可以理解地窒息。

2 个答案:

答案 0 :(得分:1)

我的猜测是,一般来说,在HTML上下文中包装XML而不执行任何特殊字符的转义并不能可靠地工作。我希望至少使用像

这样的XML文档失败
<a>
  <b>
    <html>
    </html>
  </b>
</a>

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

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

答案 1 :(得分:0)

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

代码更改是使用 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错误。

霍尔迪阿。