HTTP请求返回200 OK,但没有响应内容

时间:2014-04-29 21:08:32

标签: javascript http jboss atmosphere

在开发特定网站时,我在Firefox中加载网站时遇到了间歇性问题(无法在IE或Chrome中进行比较)。该网站加载了几个javascript文件,css样式表,图像等。偶尔,一个或多个文件无法正确加载。响应表示状态为200 OK,但内容长度表示0.这会在不同时间在不同文件上发生。当它是一个无法加载的javascript文件时,该网站无法正常运行,但仍可能显示内容。当它恰好是无法加载的index.html文件时,Firefox会显示一个空白页面,其中包含以下html:

<html>
<head></head>
<body><pre></pre></body>
</html>

(我相信这是来自Firefox的默认&#34;空&#34;页面视图)

似乎可以从浏览器缓存中正确获取以前成功的加载,并且响应状态为304 Not Modified。失败后,下次请求资源时,我们会看到200 OK的响应状态,后续请求再次响应304&。

以下是Firebug报告的请求/响应标头的示例:


一般成功案例(响应状态:304未修改,内容长度:288)

请求标题:

Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en/q=0.5
Connection: keep-alive
Cookie: JSESSIONID=<shouldn't matter>
Host: ???.???.???.???:8442
If-Modified-Since: Tue, 29 Apr 2014 13:18:26 GMT
If-None-Match: W/"228-1398777506000"
Referrer: https://???.???.???.???:8442/mySite/
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20131023 Firefox/17.0 

响应标题:

Cache-Control: no-cache
Date: Tue, 29 Apr 2014 13:36:35 GMT
Etag: W/"288-1398777506000"
Expires: Thu, 01 Jan 1970 00:00:00 GMT-00:00
Pragma: No-cache
Server: Apache-Coyote/1.1 

缓存中的响应标头:

Accept-Ranges: bytes
Cache-Control: no-cache
Content-Length: 288
Content-Type: text/javascript
Date: Tue, 29 Apr 2014 13:36:35 GMT
Etag: W/"288-1398777506000"
Expires: Thu, 01 Jan 1970 00:00:00 GMT-00:00
Last-Modified: Tue, 29 Apr 2014 13:18:26 GMT
Pragma: No-cache
Server: Apache-Coyote/1.1 

Firebug中的“缓存”选项卡指示以下内容:

Data Size: 288
Device: disk
Expires: Wed Dec 31 1969 18:00:00 GMT-06:00 (CST)
Fetch Count: 81
Last Fetched: Tue Apr 29 2014 08:28:35 GMT-05:00 (CDT)
Last Modified: Tue Apr 29 2014 08:28:35 GMT-05:00 (CDT) 

案例失败(响应状态:200 OK,内容长度:0)

请求标题:

Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en/q=0.5
Connection: keep-alive
Cookie: JSESSIONID=<same as above>
Host: ???.???.???.???:8442
If-Modified-Since: Tue, 29 Apr 2014 13:18:26 GMT
If-None-Match: W/"228-1398777506000"
Referrer: https://???.???.???.???:8442/mySite/
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20131023 Firefox/17.0 

响应标题:

Content-Length: 0
Date: Tue, 29 Apr 2014 13:36:28 GMT
Server: Apache-Coyote/1.1 

Firebug中的“缓存”选项卡指示以下内容:

Data Size: 
Device: disk
Expires: Wed Dec 31 1969 18:00:00 GMT-06:00 (CST)
Fetch Count: 83
Last Fetched: Tue Apr 29 2014 08:28:42 GMT-05:00 (CDT)
Last Modified: Tue Apr 29 2014 08:28:42 GMT-05:00 (CDT) 

下一次成功案例(响应状态:200 OK,内容长度:288)

请求标题:

Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en/q=0.5
Connection: keep-alive
Cookie: JSESSIONID=<same as above>
Host: ???.???.???.???:8442
Referrer: https://???.???.???.???:8442/mySite/
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20131023 Firefox/17.0 

响应标题:

Accept-Ranges: bytes
Cache-Control: no-cache
Content-Length: 288
Content-Type: text/javascript
Date: Tue, 29 Apr 2014 13:37:03 GMT
Etag: W/"288-1398777506000"
Expires: Thu, 01 Jan 1970 00:00:00 GMT-00:00
Last-Modified: Tue, 29 Apr 2014 13:18:26 GMT
Pragma: No-cache
Server: Apache-Coyote/1.1 

Firebug中的“缓存”选项卡指示以下内容:

Data Size: 288
Device: disk
Expires: Wed Dec 31 1969 18:00:00 GMT-06:00 (CST)
Fetch Count: 85
Last Fetched: Tue Apr 29 2014 08:28:54 GMT-05:00 (CDT)
Last Modified: Tue Apr 29 2014 08:28:53 GMT-05:00 (CDT) 

我们在JBoss-EAP v6.1中托管该网站,我在Firefox 10,17和24中尝试了这一点并得到了相同的结果。我知道有更新的版本(更不用说不同的浏览器),但它们不一定是我们的选择。我希望解决方案是一个简单的配置更改,但在我尝试搜索此问题时,我没有看到任何人遇到同样的问题,所以它可能不是那么简单。我很感激任何建议。另外,如果我需要提供更多信息(例如,web.xml,jboss.conf等),请告诉我。

混合中的其他产品:

  • Require.js v2.1.2
  • Java 1.6
  • CAS 3.2.1
  • Atmosphere 2.1.3

更新:我基本上排除了缓存问题的可能性。我按照RequireJS API页面中的建议实现了缓存清除模块加载过程,但我仍然看到了问题。但是,这一次,而不是所有304状态代码,它们都是200个。


更新2:我下载了JBossWeb 7.2.0.Final的源代码并完成了调试此问题。显然有一个名为org.apache.coyote.http11.Http11ConnectionHandler的类,它维护一个Http11Processor实例池,每个实例都有自己的Request和Response对象。请求完成后,Http11Processor将被回收&#34;并放回游泳池。

似乎回收逻辑中可能存在线程问题,因为Response.recycle应该设置&#34; commit&#34;为false,但在调用response.recycle()后立即停止,我的(条件)断点以response.committed == true停止。这是导致稍后失败的响应的原因。当Http11Processor包含已提交的Response对象时,Response不能用于返回任何信息。它只响应Status:200,Content-Length:0。

当我关闭具有使用服务器端事件的Atmosphere连接的网站时,似乎会发生这种情况。 我是否正确使用Atmosphere连接?我应该实现特殊的清理逻辑吗?

2 个答案:

答案 0 :(得分:5)

经过大量调查和调试后,我发现Atmosphere库被允许操作一个已被回收并用于以后请求的Response对象。受影响的响应的状态为200,内容长度为0,并且承诺使得不能进行其他修改。不幸的请求线程给出了这个&#34;损坏的&#34;响应实例无法用于提供实际内容。

为防止此修改影响JBoss服务器,我将以下内容添加到jboss.properties文件中:

org.apache.catalina.connector.RECYCLE_FACADES=true

另一种选择是使用安全管理器。 (参见this页面的安全性部分,以及this页面的最后几段中提供的建议)

这显然会阻止请求和响应的回收,因此我们总是为每个请求获得一个新的Response实例。

答案 1 :(得分:0)

你可能有一个try catch块,它会吞下错误而不产生输出。它可能是在某处记录错误。