为什么POST请求中的“Content-Length:0”?
提交表单时(10到40多个字段),客户有时会发送Content-Length: 0
POST请求。
我们用不同的浏览器和不同的地点对它进行了testing,但是无法重现错误。 客户正在使用Internet Explorer 7和代理。
我们要求他们让他们的系统pipe理员从他们身边看问题。 运行一些没有代理的testing等。
在此期间(半年后,仍然没有答案),我很好奇,如果有人知道与Content-Length: 0
请求类似的问题。 也许从一些Windowsnetworking内部的大公司的特殊代理。
Internet Explorer 7有一个已知的问题吗? 用代理系统? Windowsnetworking本身?
Google只在NTLM(以及这样的)身份validation的背景下展示了一些东西,但是我们并没有在Web应用程序中使用它。 也许这是代理服务器在Windowslogin的客户networking中运行的方式? (我不是Windows专家,只是猜测。)
我没有关于基础设施的更多信息。
更新: 2010年12月,有可能通知一个pipe理员这个,包括。 链接从这里的答案。 联系是由于代理也造成的另一个问题。 从那以后没有反馈。 而错误信息仍然存在。 我正在笑,以防止我哭泣。
更新2:这个问题自2008年中以来就存在了。每隔几个月,客户就会感到恼火,并希望尽快修复。 我们再次发送所有旧电子邮件,并要求他们联系他们的pipe理员修复或进行一些进一步的testing。 2010年12月,我们能够向1位pipe理员发送一些信息。 没有反馈。 问题不是固定的,我们不知道他们是否尝试过。 而在2011年5月,客户再次写道,并希望这是固定的。 自2008年以来拥有所有信息的同一个人。
感谢所有的答案。 我从这里的一些评论中可以看出,你帮了很多人。 现实世界太糟糕了,这对我来说是怪诞的。
更新3: 2012年5月,我想知道为什么我们没有收到另一个需求来解决这个问题(见更新2)。 看着错误协议,每次发生这种错误(每天大约15次)只报告这个错误。 它停止了2012年1月底。没有人说什么。 他们一定在networking上做了些什么。 一切都好了。 从2008年夏天到2012年1月。太糟糕了,我不能告诉你他们做了什么。
更新4: 2015年9月。网站必须收集一些数据并将其传送到客户的主要网站。 有一个帐户的API。 每当有问题的时候联系我们,即使问题明显在另一边。 现在几个星期,我们不能给他们发送数据。 该帐户不可用了。 他们有一个重新启动,我不能再find使用我们网站的数据的网页。 错误报告没有回答,也没有人投诉。 我想他们刚刚结束了这个项目。
更新5: 2017年3月。该API在2015年夏天停止工作。客户似乎继续为该网站付费,并且仍在2017年2月访问该网站。我猜他们将其用作存档。 他们不会创build或更新任何数据,所以这个bug在2012年1月的神秘修复之后可能不会重新出现。但这会是别人的问题。 我走了。
如果Internet Explorer从已validation的站点(NTLM)发布到未validation的站点(匿名),则不会发送表单字段。
这是针对challange-响应情况(NTLM-或Kerberos-安全的网站)的function,IE可以期望第一个POST请求立即导致HTTP 401 Authentication Required响应(包括挑战),并且只有第二个POST请求其中包括对challange的回应)实际上将被接受。 在这些情况下,由于性能原因,IE不会上载可能较大的请求主体。 感谢EricLaw在评论中发布这些信息。
每当HTTP POST从NTLM身份validation(即Intranet)页面到非身份validation(即Internet)页面,或者如果未经身份validation的页面是框架集的一部分,其中框架集页面进行身份validation时,就会出现此问题。
解决方法是使用GET请求作为表单方法,或者确保未经身份validation的页面在新的选项卡/窗口(collections夹/链接目标)中打开,而没有部分身份validation的框架集。 一旦整个窗口的authentication模式一致,IE就会重新开始发送表单内容。
- 绝对相关: http : //www.websina.com/bugzero/kb/browser-ie.html
- 可能相关: KB923155
- 完整说明 : IEInternals博客 – 质询 – 响应身份validation和零长度post
这很容易在MS-IE和服务器端的NTLMauthenticationfilter中重现。 我在XP-SP2上遇到了与JCIFS(1.2。 ),struts 1.和MS-IE 6/7相同的问题。 终于修好了 有几个解决方法来弥补。
-
从POST(struts默认设置)更改表单方法为GET。 对于大多数小页面的页面,效果很好。 不幸的是,我可能有超过50个logging在HTTPstream中发送回服务器端。 IE的GET URL限制为2038字节(不是参数长度,而是整个URL的长度)。 所以这是一个快速的解决方法,但不适用于我。
-
在执行POST动作之前发送一个GET。 这在MS-KB中是推荐的。 我的项目有很多遗留程序,我不会在适当的时候冒险。 我从来没有尝试过,因为它仍然需要一些额外的authentication处理时,基于我从MS-KB的理解,filter层接收GET,我不想改变与其他浏览器,如Firefox,Opera的行为。
-
检测POST是否以零内容长度发送(您可以从您的框架的头部属性散列结构中获得)。 如果是这样,通过从DC或caching中获取质询代码触发NTLMauthentication周期,并期待NTLM响应。 当收到NTLM type2 msg并且会话仍然有效时,如果POST内容长度不为零,则不需要对用户进行身份validation,而只是将其转发给预期的操作。 顺便说一句,这会增加networkingstream量。 因此,在应用更改plz之前,请检查您的caching生存时间设置和SMB会话soTimeOutconfiguration。 或者更简单的,你可以发送一个401未授权的状态到MS-IE,浏览器将发回POST请求和回复的数据。
-
MS-KB提供了一个KB-923155的热修复(由于声誉数字很低({),我无法发布多个链接,但似乎不起作用。 有人会在这里发布一个可行的热修复? 谢谢:)这里有一个供参考的链接, http://www.websina.com/bugzero/kb/browser-ie.html
我们的系统上有一个客户,完全一样的问题。 我们已经把它指向代理/防火墙。 微软的IAS。 它剥离POST正文并发送内容长度:0.然而,我们可以做的不是很多,而是想要使用GET请求,因为这暴露了URLstring上的用户名/密码等。 我们的系统中有近7,000个用户,只有一个出现问题…也只有一个使用Microsoft IAS,所以它必须是这个。
这个问题很可能是代理服务器之间实现HTTP 1.0。
在HTTP 1.0中,您必须使用Content-Length标题字段:( 请参阅第10.4节 )
所有的HTTP / 1.0 POST请求都需要一个有效的Content-Length。 如果HTTP / 1.0服务器无法确定请求消息内容的长度,则应该使用400(错误请求)消息进行响应。
进入代理的请求是HTTP 1.1,因此不需要使用Content-Length头字段。 内容长度标题通常被使用但不总是。 请参阅以下摘录自HTTP 1.1 RFC S. 14.13 。
应用程序应该使用这个字段来表示消息体的传输长度,除非4.4节中的规则禁止。 任何内容长度大于或等于零是一个有效的值。
4.4节描述了如果没有给出Content-Length,如何确定消息体的长度。
因此,代理服务器不会看到Content-Length头,如果存在主体,它将在HTTP 1.0中绝对需要。 所以它假定为0,以便请求最终到达服务器。 请记住,代理不知道HTTP 1.1规范的规则,所以当没有Content-Length头时,它不知道如何处理这种情况。
您是否100%确定您的请求是指定Content-Length标头? 如果它使用第4.4节中定义的其他方法,因为它认为服务器是1.1(因为它不知道中间的1.0代理),那么你将会遇到你所描述的问题。
也许你可以使用HTTP GET来绕过这个问题。
这是Internet Explorer 6已知的问题,但不是我知道的7。 您可以安装此修复程序的IE6 KB831167修复程序。
你可以在这里阅读更多 。
一些问题给你:
- 你知道哪种types的代理?
- 你知道在请求中是否有实际的身体发送?
- 每次都会一致吗? 还是只有时候?
- 请求中是否发送了二进制数据? 也许数据以\ 0开头,代理有二进制数据的错误。
如果用户正在使用使用NTLM身份validation的ISA代理,那么听起来像这个问题,它提供了一个解决scheme(ISA代理的补丁)
http://support.microsoft.com/kb/942638
POST请求没有POST正文可能会被发送到ISA Server 2006中发布的Web服务器
你确定这些请求是来自“客户”?
我以前有过这个问题, 他们有时会根据在爬网过程中发现的FORM标记中的操作URI发送空白的POST请求来探测“联系我们”表单的网站。
HTTP中的ContentLength头的存在和可能的值在HTTP(我假设为1/1)RFC:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13
在HTTP中,只要在传输之前可以确定消息的长度,就应该发送它
也可以看看:
如果同时收到一个Transfer-Encoding头域和一个Content-Length头域,则后者必须被忽略。 http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4
也许你的消息带有一个Transfer-Encoding头部?
稍后编辑:也请注意在RFC中使用的“SHOULD”非常重要,不等同于“必须”:
3.应该这个词或“推荐”这个形容词意味着在特殊情况下可能存在某个特定项目的正当理由,但是在select不同的课程之前,必须理解和仔细权衡全部的含义。 参考: http : //www.ietf.org/rfc/rfc2119.txt
在https连接达到keepalive超时并重新连接到服务器之后,Google也会将其显示为IE(某些版本)。 该解决scheme似乎是configuration服务器不使用HTTPS下的Keepalive的IE浏览器。
Microsoft的KB821814的修补程序可以将Content-Length设置为0:
本文介绍的修复程序将在Wininet.dll中实现一个代码更改为:
- 检测POST请求上的RESET条件。
- 保存要发布的数据。
- 重试内容长度设置为0的POST请求。这样可以防止发生重置,并允许完成身份validation过程。
- 重试原始的POST请求。
我们有一位客户使用匿名和NTLM模式(在不同的端口上)使用同一个网站。 我们发现在我们的例子中,401与用于http优化的Riverbed Steelhead应用程序相关。 第一个信号指向我们的方向是X-RBT-Optimized-By标题。 问题是免费的401function:
此function可以用于每个请求和每个连接的身份validation,但是与每个请求的身份validation一起使用时,它是最有效的。 使用每个请求的身份validation,每个请求都必须在服务器将对象提供给客户端之前对服务器进行身份validation。 但是,大多数浏览器不会caching需要validation的服务器响应,因此每次GET请求都会浪费一次往返。 使用免费401,客户端Steelhead设备将caching服务器响应,当客户端发送没有任何validation头的GET请求时,它将在本地响应-401Unauthorized‖消息,从而节省往返。 请注意,HTTP模块不参与实际身份validation。 HTTP模块做的是通知客户端服务器需要authentication而不需要浪费一次往返。
当configuration为使用HTTP代理时, curl
发送PUT/POST
请求,其Content-Length: 0
。 在第一个未经授权的PUT/POST
请求代理的情况下,克服需要的缓冲是一个窍门。 如果GET/HEAD
请求curl
只是重复查询。 PUT/POST
的scheme如下所示:
-
发送
Content-Length
设置为0的第一个PUT/POST
请求。 -
获取答案。 HTTP状态代码407意味着我们必须使用代理授权。 为发送请求准备代理validation头。
-
再次发送请求时使用填充标头进行代理validation,并将实际数据发送到POST / PUT。
我也有一个问题,来自客户的IE 11浏览器的请求具有Content-Length: 0
并且不包括预期的POST内容。 当客户使用Firefox或Chrome时,预期内容包含在请求中。
我找出原因是客户使用HTTP URL而不是HTTPS URL(例如http://...
,而不是https://...
),我们的应用程序使用HSTS。 看来在IE 11中可能有一个错误,当请求由于HSTS而升级到HTTPS时,请求内容会丢失。
让客户将URL更正为https://...
导致内容被包含在POST请求中并解决了问题。
在这个阶段,我还没有调查过它是否实际上是IE 11中的一个bug。