重新访问GWT-RPC和臭名昭着的偶发“StatusCodeException:0”异常

时间:2014-07-30 11:34:00

标签: gwt xmlhttprequest subdomain same-origin-policy gwt-rpc

我的问题是在通过子域https://sub.site.com/访问页面时使用 GWT 2.6.1 时发生的infamous "StatusCodeException: 0"问题。

现在,对于使用IE11的一个客户而言,这种情况非常零星,并且我无法使用IE11从几台不同的计算机重现 ,IE10,IE9或IE8(不是谈论Chrome或Firefox)。

https://site.com/访问完全相同的webapp似乎对该客户来说很好。

这显然让我得出结论,我对Same Origin Policy有疑问。

但奇怪的是,我的 webapp设计的方式是没有跨域跨子域请求。同样适用于 no cross-protocol 以及 no cross-port 请求。换句话说,在这种情况下,不会违反同源政策。作为对此的确认,我可以提供以下证据:

  

在客户网站上我已经看到如何重现客户启动使用应用并且一切正常很好 - 所有请求都正常返回响应。然后,经过几分钟工作后,相同的请求在同一页面上(没有重新加载)开始失败 StatusCodeException: 0

基本上,https://sub.site.comhttps://site.com都指向相同的IP,并且只有一个Tomcat webapp https://sub.site.comhttps://site.com提供完全相同的资源DashboardService

另一个证据是单个GWT模块本身的代码库:我只使用一个名为public class DashboardModule extends EntryPoint implements IDashboardModule { private final DashboardServiceAsync dashboardService = createDashboardService(); @Override public void onModuleLoad() { // loading of module elements // dashboardService is passed as a parameter so only one instance is used } /** * PLEASE SEE QUESTION #1 BELOW CODE SNIPPET */ private static final String DASHBOARD_REQUEST_URL = "request"; private static DashboardServiceAsync createDashboardService() { final DashboardServiceAsync service = GWT.create(DashboardService.class); ((ServiceDefTarget) service).setServiceEntryPoint(DASHBOARD_REQUEST_URL); return service; } } 的服务的一个实例:

ERROR_INTERNET_INTERNAL_ERROR An internal error has occurred.

===================================编辑======== ============================

在客户位置查看控制台后,错误始终如下:

SCRIPT7002:XmlHttpRequest:网络错误0x2ee4,...

所以它似乎与同源政策无关,因为根据this article,它被描述为{{1}}

很遗憾,但是我发现只有2次提到这个错误但没有解决: Error under IE10Error under IE11

我假设客户很可能通过某些代理访问网站,稍微改变了请求,IE无法处理它们。

问题1:有谁知道如何在本地模拟或重现上述错误?

问题2:是否有人知道如何优雅地解决这个问题?

问题3:是否可以简单地重试请求,或者此请求可能已到达服务器并进行修改,因此重试它可能会产生重复修改?

将尝试设置转发代理以模拟可能的客户设置,以至少重现上述错误...

我非常感谢任何帮助!

1 个答案:

答案 0 :(得分:8)

好的,所以在为一个工作周找到这个问题之后我终于设法解决了。

实际上,当我在Tomcat前面安装Apache2服务器并使用IE11从另一个VirtualBox Win7主机访问它时,我能够在本地重现非常类似的问题。这给了我零星的StatusCodeException: 0 Network error 0x2ef3但行为非常相似:一分钟左右后GWT-RPC请求开始失败。这在IE10和IE11中是可重现的,但在IE8和IE9中运行良好:)( IE在新版本中变得更加糟糕吗?

本地我只需通过向Keep-alive Apache2 ssl配置文件添加以下行来禁用IE浏览器的/etc/apache2/sites-enabled/default-ssl.conf功能即可解决该问题:

    # following line was added
    BrowserMatch "Trident" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0

</VirtualHost>
</IfModule>

这基本上告诉Apache2不要使用keep-alive,使用 特殊 SSL处理,并且通常在请求中user-agent字符串时降级为HTTP 1.0标准有Trident个字(匹配IE11和IE10以及可能更早的IE)

这为每个响应添加了Connection: close HTTP标头,似乎在本地中正常工作。

在客户网站上,这仍然无法正常工作并生成相同的Network error: 0x2ee4

值得注意的是,客户使用 McAfee Web Gateway 作为位于浏览器中间的转发代理&lt; - &gt;服务器通信。

长话短说,我发现问题出在以下方面:当页面加载时,有多个 GET 请求被发送到服务器以获取页面,资源等。然后10秒后使用它(我的webapp是单页面应用程序,因此用户可能在同一页面上花费超过10分钟)只有 GWT-RPC 请求正在服务器 POST 请求。在使用此页面一分钟后(我怀疑1分钟= keep-alive timeout代理服务器)这些POST请求随机失败,并出现0x2ee4网络错误。

在我实现了GWT-RPC重试功能之后,我发现在重试30秒后,只有所有 GWT-RPC请求失败并出现上述错误。刷新页面再次解决了这个问题一分钟左右然后发生同样的故事。

所以,我发现 CRAPPY IE11和IE10 错误地处理了SSL,保持活动和POST请求的组合。似乎сrappyIE10和IE11 根本无法使用POST请求续订keep-alive ssl连接,只能使用GET请求执行此操作。 请注意,Chrome,Firefox和其他普通浏览器都能很好地处理这种情况。在Firebug中检查Firefox在这种情况下的行为时:可以清楚地看到POST请求已经完成,然后显示为中止0.5秒,然后显示为成功(我怀疑Firefox处理这种特定情况,向服务器本身发出GET请求以更新SSL保持连接,然后重试POST请求)

因此,为了解决IE中的这个问题,我只是实现了每隔5秒就用“GET”请求“ping”服务器的功能(准备好尝试这个时间,因为这很可能与客户的代理keep-alive超时有关)

这使它工作(请注意,在这种情况下不需要上面的Apache2配置hack)

我真的希望这能帮助有类似问题并节省时间的人

使用的资源:

  1. IE Network Error 0x2ef3 question 1
  2. IE Network Error 0x2ef3 question 2
  3. IE Network Error 0x2ef3 question 3
  4. Awesome q&a on how to implement transparent GWT-RPC retry functionality
  5. P.S。我会向Microsoft报告此IE10和IE11问题吗? - 在我已经花了一个多星期的时间找出问题后,我真的不急于花费30多分钟的时间来报告商业糟糕的IE浏览器问题。

    我坚持 推荐Chrome Firefox 其他普通浏览器作为可行的替代方案,我仍然认为 IE11不适合现代网站使用AJAX