重新审视 GWT-RPC 和臭名昭著的零星“StatusCodeException:0”异常

Posted

技术标签:

【中文标题】重新审视 GWT-RPC 和臭名昭著的零星“StatusCodeException:0”异常【英文标题】:GWT-RPC and the infamous sporadic "StatusCodeException: 0" exception revisited 【发布时间】:2014-09-22 00:48:06 【问题描述】:

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

现在,对于使用 IE11 的一位客户偶尔会发生这种情况,并且我无法在几台使用 IE11、IE10 的不同计算机上重现这种情况, IE9 或 IE8(不谈 Chrome 或 Firefox)。

https://site.com/ 访问完全相同的 web 应用程序似乎对该客户来说工作正常。

这显然让我得出结论,我在使用 Same Origin Policy 时遇到问题。

但奇怪的是,我的 webapp 的设计方式没有跨域跨子域请求。 no cross-protocol 以及 no cross-port 请求也是如此。换言之,同源政策在这种情况下没有被违反。作为确认,我可以提供以下证据:

在客户现场我看到这是如何复制的客户开始使用应用程序并且一切正常 - 所有请求都正常返回响应。然后,工作几分钟后,同一页面上的完全相同的相同请求(无需重新加载)开始失败并出现StatusCodeException: 0.

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

另一个证明是单个 GWT 模块本身的代码库:我只使用一个名为 DashboardService 的服务的一个实例:

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;
    

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

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

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

所以这似乎与同源政策无关,因为根据this article,它被描述为ERROR_INTERNET_INTERNAL_ERROR An internal error has occurred.

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

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

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

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

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

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

非常感谢任何帮助!

【问题讨论】:

这不是 SOP 违规。其他客户是否使用您的网络应用程序?如果是这样,我建议客户进行特殊会话处理。 @deterministicFail 我也想过网络问题,但令人怀疑的是,为什么它在 https://site.com/ 上为该客户正常工作。 @deterministicFail 你是对的 - 这不是 SOP 违规,这是一些内部网络错误 - 请查看我的编辑。你对此有什么想法吗?我将非常感谢任何帮助,因为我已经花了 2 天时间试图解决这个问题 如果是发布请求,您的认证可能有问题。 connect.microsoft.com/IE/feedback/details/877525/…***.com/questions/16312938/… @deterministicFail 好的,我会检查的。非常感谢提示 【参考方案1】:

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

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

本地我可以通过在/etc/apache2/sites-enabled/default-ssl.conf Apache2 ssl 配置文件中添加以下行来简单地禁用 IE 浏览器的Keep-alive 功能来解决这个问题:

    # 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 字符串具有Trident,通常会降级到 HTTP 1.0 标准word(匹配 IE11 和 IE10 以及可能更早的 IE)

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

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

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

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

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

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

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

这使它起作用(请注意,在这种情况下不需要上述 Apache2 配置破解)

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

使用的资源:

    IE Network Error 0x2ef3 question 1 IE Network Error 0x2ef3 question 2 IE Network Error 0x2ef3 question 3 Awesome q&a on how to implement transparent GWT-RPC retry functionality

P.S. 我会向 Microsoft 报告这个 IE10 和 IE11 问题吗? - 在我已经花了一个多星期的时间找出问题之后,我真的不想花 30 多分钟的时间来报告商业蹩脚的 IE 浏览器问题。

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

【讨论】:

感谢您的调查。我确信重试机制应该可以工作。但你打开了我的眼睛。

以上是关于重新审视 GWT-RPC 和臭名昭著的零星“StatusCodeException:0”异常的主要内容,如果未能解决你的问题,请参考以下文章

重新审视进程间的通信

今天,我开始重新审视我的大学生活

重新审视技术

重新审视技术

可怕的 MySQL 导入编码问题 - 重新审视

杂文重新审视 ViT 中的 Token 表示