HTTP 请求返回 200 OK 但没有响应内容 [英] HTTP Request returns 200 OK but no content in response

查看:42
本文介绍了HTTP 请求返回 200 OK 但没有响应内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In developing a particular web site, I have an intermittent issue when loading the site in Firefox (haven't been able to compare in IE or Chrome). The site loads several javascript files, css stylesheets, images, etc. Occasionally, one or more of the files fail to load properly. The response indicates a status of 200 OK, but the content-length indicates 0. This happens on different files at different times. When it is a javascript file that fails to load, the site does not function properly, but may still display content. When it happens to be the index.html file that fails to load, Firefox displays an empty page with the following html:

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

(我相信这是来自 Firefox 作为默认的空"页面视图)

(I believe this comes from Firefox as the default "empty" page view)

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

It appears that previous successful loads may be fetched properly from the browser cache, and the response status is 304 Not Modified. After a failure, the next time the resource is requested we see a response status of 200 OK, with subsequent requests again responding with 304's.

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

Here are examples of the request/response headers as reported by Firebug:

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

General Success Case: (Response Status: 304 Not Modified, Content-length: 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)


Failed Case: (Response Status: 200 OK, Content-length: 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)


Next Success Case: (Response Status: 200 OK, Content-length: 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 等),请告诉我

We are hosting the site in JBoss-EAP v6.1, and I have tried this in Firefox 10, 17 and 24 with the same results. I understand there are newer versions available (not to mention different browsers), but they aren't necessarily an option for us. I'm hoping the solution is a simple configuration change, but in my attempts at searching for this issue I have not seen anyone having the same problem, so it may not be so simple. I appreciate any suggestions. Also, please let me know if I need to provide more information (e.g., web.xml, jboss.conf, etc)

混合中的其他产品:

  • Require.js v2.1.2
  • Java 1.6
  • CAS 3.2.1
  • 大气 2.1.3

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

Update: I have essentially ruled out the possibility of a cache issue. I implemented a cache busting module load process as suggested in the RequireJS API page, and I still see the problem. This time, however, instead of all of the 304 status codes, they are all 200's.

更新 2: 我下载了 JBossWeb 7.2.0.Final 的源代码并调试了这个问题.显然有一个名为 org.apache.coyote.http11.Http11ConnectionHandler 的类,它维护着一个 Http11Processor 实例池,每个实例都有自己的 Request 和 Response 对象.当一个请求完成时,Http11Processor 被回收"并放回池中.

Update 2: I downloaded the source for JBossWeb 7.2.0.Final and worked through debugging this issue. Apparently there is a class called org.apache.coyote.http11.Http11ConnectionHandler that maintains a pool of Http11Processor instances, each with its own Request and Response objects. When a request is completed, the Http11Processor is "recycled" and put back into the pool.

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

It appears that there may be a threading issue in the recycling logic because the Response.recycle is supposed to set the "committed" to false, but my (conditional) breakpoint immediately after call to response.recycle() stops with response.committed == true. This is what causes the failed responses later on. When a Http11Processor that contains an already committed Response object, the Response can not be used to return any information. It simply responds with Status: 200, Content-Length: 0.

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

This seems to be happening when I close a website that has an Atmosphere connection that uses Server Side Events. Am I using the Atmosphere connection improperly? Is there special cleanup logic I should be implementing?

推荐答案

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

After a lot of investigation and debugging, I found out that the Atmosphere library was being allowed to manipulate a Response object that had been recycled and getting used for a later request. The affected Response was given a status of 200, content-length of 0, and it was committed such that no other modifications could be made. The unlucky request thread that is given this "corrupted" Response instance is unable to be used to provide the actual content.

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

To prevent this modification from affecting the JBoss server, I added the following to the jboss.properties file:

org.apache.catalina.connector.RECYCLE_FACADES=true

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

Another option is to use a Security Manager. (See the Security section of this page, and the advice offered in the last few paragraphs of this page)

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

This apparently prevents recycling of requests and responses, so we always get a fresh Response instance for each request.

这篇关于HTTP 请求返回 200 OK 但没有响应内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆