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

标签 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 作为默认的“空”页面 View )

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

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

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

请求 header :
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 

响应 header :
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 

来自缓存的响应 header :
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 中的 Cache 选项卡指示以下内容:
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)

请求 header :
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 

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

Firebug 中的 Cache 选项卡指示以下内容:
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)

请求 header :
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 

响应 header :
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 中的 Cache 选项卡指示以下内容:
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 被“回收”并放回池中。

    似乎在回收逻辑中可能存在线程问题,因为 Response.recycle 应该将“已提交”设置为 false,但我的(条件)断点在调用 response.recycle() 后立即停止 response.committed = =真。这就是导致稍后响应失败的原因。当一个 Http11Processor 包含一个已经提交的 Response 对象时,该 Response 不能用于返回任何信息。它只是响应状态:200,内容长度:0。

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

    最佳答案

    经过大量调查和调试,我发现 Atmosphere 库被允许操作一个已被回收并用于以后请求的 Response 对象。受影响的响应的状态为 200,内容长度为 0,并且已提交,因此无法进行其他修改。被赋予此“损坏”响应实例的不幸请求线程无法用于提供实际内容。

    为了防止这种修改影响 JBoss 服务器,我在 jboss.properties 文件中添加了以下内容:

    org.apache.catalina.connector.RECYCLE_FACADES=true
    

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

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

    关于javascript - HTTP 请求返回 200 OK 但没有响应内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23375313/

    相关文章:

    javascript - 如何使用 JavaScript 加载跨域页面

    android - UTF-8 的 MultipartEntityBuilder 和 setCharset 发送空内容

    java - weblogic 10.3 上的 ClassCastException jboss-seam

    javascript - 使用部分字符串循环数组

    javascript - 有一个javascript函数私下跟踪它的调用次数

    javascript - 加载到模态时,具体化选项卡不起作用

    javascript - 通过 Angular http 请求发布文件

    python-2.7 - 如何使用 Tornado 发送 HTTP 广播消息?

    ssl - JBoss 相互证书身份验证在 SSL 握手时失败

    java - JBoss MQ教程