我的问题是在通过子域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.com
和https://site.com
都指向相同的IP,并且只有一个Tomcat webapp 为https://sub.site.com
和https://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 IE10和Error under IE11。
我假设客户很可能通过某些代理访问网站,稍微改变了请求,IE无法处理它们。
问题1:有谁知道如何在本地模拟或重现上述错误?
问题2:是否有人知道如何优雅地解决这个问题?
问题3:是否可以简单地重试请求,或者此请求可能已到达服务器并进行修改,因此重试它可能会产生重复修改?
将尝试设置转发代理以模拟可能的客户设置,以至少重现上述错误...
我非常感谢任何帮助!
答案 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)
我真的希望这能帮助有类似问题并节省时间的人
使用的资源:
P.S。我会向Microsoft报告此IE10和IE11问题吗? - 在我已经花了一个多星期的时间找出问题后,我真的不急于花费30多分钟的时间来报告商业糟糕的IE浏览器问题。
我坚持 推荐Chrome 或 Firefox 或其他普通浏览器作为可行的替代方案,我仍然认为 IE11不适合现代网站使用AJAX