Apache 2.0手册中文版翻译项目 [本文译者: suncjs * ]

项目说明 | 项目进度 | 项目讨论区 | Apache手册中文版

 


关于客户端的已知问题 - Apache HTTP服务器
<-
Apache主站 > HTTP服务器 > 文档 > 2.0版本 > Miscellaneous Documentation

关于客户端的已知问题

警告:

此文档没有考虑到Apache HTTP服务器 2.0 版本中的变化并为之作完全更新。 其中某些信息可能仍然有效,但使用时请小心。

一直以来Apache Group都在发现和得到关于各种各样的我们必须与之一起工作的客户端的问题或者解释。 本文描述这些问题及可用的变通办法。还没有进行任何整理。虽然本文假定读者对标准有一定的熟悉, 但不是必需的。

为了简洁,Navigator指Netscape的Navigator产品(较晚的版本被改名为 "Communicator"和其他不同的名字),MSIE指Microsoft's Internet Explorer产品。 所有的商标和版权属于它们各自的公司。我们欢迎各种客户端的作者们校正文中不一致之处, 或者向我们提供出现问题及改正问题的确切的产品版本号。

作为参考,RFC1945 定义了HTPP/1.0,及RFC2068 定义了HTTP/1.1。1.2版本的Apache是一个HTTP/1.1服务器(带有一个可选的 HTTP/1.0 代理)。

这些变通办法的种类被环境变量触发。典型地,管理员用mod_browser控制设置哪一个变量及为什么客户端设置。 除非以其他方式注明,在 1.2 及以后版本中都有所有这些办法。

top

POSTs后面跟着的CRLF

这是一个遗留问题。CERN web 服务器要求POST数据时最后要跟一个附加的CRLF。 因此许多客户端会发送一个额外的CRLF,而且不计入请求头中的Content-Length。 Apache对这个问题的解决办法是忽略掉一个请求之前的所有空行。

top

被中断的KeepAlive

各种各样的客户端都已经有了对付被中断的keepalive(持久连接)的机制。 特别地,Windows版本的Navigator 2.0 会在服务器使一个空置连接超时的时候被搞昏头。 缺省的配置文件中提供了解决办法:

BrowserMatch Mozilla/2 nokeepalive

注意这也可以用于一些早期版本的MSIE,就是那些在客户浏览器标示字符串中像Navigator一样称自己为Mozilla的。

MSIE 4.0b2,声称支持 HTTP/1.1,但不能在收到 301 或者 302(重定向)应答的时候正确处理Keepalive。 不幸的是早于1.2.2版的Apache nokeepalive 代码不能与 HTTP/1.1 客户一起工作。 你必须为1.2.2版本打一个 补丁,再把这个加入配置文件:

BrowserMatch "MSIE 4\.0b2;" nokeepalive

top

应答中HTTP/1.1的不正确的解释

引自RFC1945的3.1节:

HTTP 使用 "<主版本号MAJOR>.<子版本号>" 这样的编号模式来表示协议的版本。 协议的版本策略有目的的允许发送者说明消息的格式和容量以便理解进一步的HTTP通讯, 而不是经由从通讯中取得的特性。

既然 Apache 是一个 HTTP/1.1 服务器,它也是这样作为应答的一部分来说明的。 许多客户端的作者错误地对待了应答消息,把这一部分当作是响应本身使用的协议的说明, 因而拒绝接受这样的响应。

关于这个问题的第一个主要说明是关于AOL的代理服务器。当 Apache 1.2 进入 beta 测试的时候, 它是第一个普遍使用的 HTTP/1.1 服务器。经过一席讨论,AOL 修正了他们的代理服务器。 由于预计到类似的问题,force-response-1.0环境变量被加入到 Apache 中。 现在,Apache 将会在发给 HTTP/1.0 客户的响应中说明为 "HTTP/1.0",但不会以其他任何方式改变这个响应。

Java Development Kit (JDK) 1。1 之前的版本也表现出这个问题,它在许多客户端中有应用(包括Navigator 3.x 和 MSIE 3.x)。 在 JDK 1.1 早期的预发布版中也是这样。我们认为这个问题在 JDK 1.1 发行版中已经解决了。不管怎样,解决办法可以是:

BrowserMatch Java/1.0 force-response-1.0
BrowserMatch JDK/1.0 force-response-1.0

来自Progressive Networks的RealPlayer 4.0 也表现出这个问题。虽然它们已经在版本 4.01 的播放器中修正了, 但 4.01 版使用了与 4.0 同样的User-Agent。解决办法仍然是

BrowserMatch "RealPlayer 4.0" force-response-1.0

top

请求使用HTTP/1.1但响应必须是HTTP/1.0

MSIE 4.0b2 有这个问题。它的 Java 虚拟机以HTTP/1.1格式发送请求但响应必须是HTTP/1.0格式 (特别是它不能理解chunked响应)。解决办法是欺骗Apache使它相信进来的请求就是HTTP/1.0格式。

BrowserMatch "MSIE 4\.0b2;" downgrade-1.0 force-response-1.0

解决办法可用于 1.2.2,还有一个 补丁用于 1.2.1.

top

头解析的边界问题

从 2.0 到 4.0b2 (可能还包括更晚的版本)所有版本的Navigator遇到响应头尾端的 CRLF位于响应消息偏移256,257或258处时有这个问题。一个为之设定的BrowserMatch会匹配几乎所有的情况, 因此针对所有请求的解决办法被自动激活了。已实现的解决办法会在这种情况可能发生的时候进行检测并为请求头添加 额外的填充数据来把拖尾的CRLF推到响应的偏移258之后。

top

多部应答(注:Multipart responses)和双引号包围的分界字符串

对于多部应答某些客户端将不接受包围分界字符串的引号(")。MIME标准推荐这样使用引号。 但是那些客户端很可能是基于RFC2068的例子编写的,那个就没有包括引号。 Apache 为了解决这个问题,在它的分界字符串中没有使用引号。

top

字节范围(Byterange)请求

字节范围请求被用于当客户端希望取得对象的一部分而不必是整个对象的时候。 在很早的一个草案中包括有URL中的字节范围。像 Navigator 2.0b1 和 MSIE 3.0 for the MAC 存在这种行为, 在服务器的日志中会出现试图访问加上了后缀";xxx-yyy"的URL的纪录(访问失败)。Apache完全不打算实现这个功能。

随后的一个草案定义了头标示Request-Range和返回类型multipart/x-byteranges。 HTTP/1.1 标准纳入了这个草案,又作了一些修正,定义了头Range和类型multipart/byteranges

Navigator (版本 2 和 3) 同时发送RangeRequest-Range头(以相同的值), 但不接受multipart/byteranges响应,应答必须是multipart/x-byteranges。 作为解决办法,如果 Apache 接收到Request-Range头它就会认为这个比Range 头高优先级并在应答中使用multipart/x-byteranges

Adobe Acrobat Reader 插件广泛使用了字节范围,在高于3.01的版本中只支持multipart/x-byterange响应。 不幸的是找不到这个插件产生请求的线索。如果插件用于Navigator,上述的解决方法会工作得很好。 但要是用在 MSIE 3 (Windows上),那个办法就没用了,因为 MSIE 3 不会像 Navigator 那样给出Range-Request。 为了解决,Apache 特别在User-Agent串中寻找 "MSIE 3"并为之使用multipart/x-byteranges. 注意为了 MSIE 3 这样做的必要性其实是因为 Acrobat 插件,而不是因为浏览器本身。

Netscape Communicator 似乎不会发出非标准的Request-Range头。 当在它上面使用早于 3.01 版的Acrobat插件时,它将不能正确理解字节范围。用户应该升级Acrobat reader 到 3.01。

top

Set-Cookie头不能合并使用

HTTP规范说把多个具有不同名字的头合并为一个是合法的(以逗号分隔)。 而一些支持Cookie的浏览器不喜欢合并后的头,更愿意接受分开发送的每个Set-Cookie头。 当解析由CGI返回的头时,Apache将明白地避免合并任何Set-Cookie头。

top

Expires头和GIF89A动画

如果第一个响应包括一个Expires头,版本2到4的Navigator会错误地 在GIF89A动画的每一个循环中重新请求这个动画。不管过期时间设为多久这都会发生。 Apache没有提供解决办法,但是有黑客提供了 1.2版和 1.3版的补丁。

top

没有Content-LengthPOST

在特定的环境下Navigator 3.01 到 3.03 的版本似乎会不正确地产生一个没有请求内容的POST请求。 没有已知的解决办法。这问题已经在 Navigator 3.04 中修正了, Netscapes 提供了一些相关信息。 还有一些关于这个的实际问题的 信息

top

JDK 1.2 betas 丢失部分响应。

如果响应头和内容的的第一部分在同一个网络封包中被发送而且使用了keep-alive的话, JDK 1.2 beta2和beta3中的http client会丢弃响应的第一部分。任何一条不满足,它都会工作得很好。

参看java developer connection的Bug-ID's 4124329 和 4125538。

如果你遇到这个问题,可以加入下列浏览器匹配指令来解决:

BrowserMatch "Java1\.2beta[23]" nokeepalive

我们不提倡使用beta测试版,因为迁就beta版的软件通常不是好主意; 理想情况是错误被改正,推出新的beta或者最终发行版,不再有人使用旧的有问题的软件。理论上。

top

Content-Type的改变在刷新后不被注意

Navigator (所有版本?) 会缓存content-type作为一个“永久”对象。 使用reload或者shift-reload不会让Navigator去注意content-type的改变。 唯一的办法是用户去清空caches(memory和disk)。作为一个例子,有些伙计可能会使用旧的 mime.types文件,这种文件不会映射.htmtext/html类型, 这种情况下,Apache 缺省地会发送text/plain。如果用户请求这个页面就会以 text/plain提供服务。在某个管理员修改服务器以后,用户将不得不在对象被正确地以 text/html类型显示之前清空他们的caches。

top

MSIE Cookie 在2000年的日期失效问题

MSIE 版本 3.00 和 3.02 (没打Y2K补丁时)不能正确处理失效日期在2000年的cookie。 2000 年之前之后都没问题。这个问题在 IE4.01 service pack 1 中被修正,Y2K 补丁 IE3.02也能解决。 用户应该避免使用2000年的失效时期。

top

Lynx不正确地请求透明内容协商

Lynx浏览器 2.7 和 2.8 在它们的请求里发送"negotiate:trans"头,这个用于表示浏览器支持透明内容协商(TCN)。 然而这个浏览器并不支持TCN。从 1.3.4 版起,Apache支持TCN,这就引起与那些版本的lynx的问题。 作为一个解决办法,未来的 Apache 版本会忽略lynx客户端发送的这个请求头。

top

MSIE 4.0 对变化响应头处理不当

MSIE 4.0 不会正确处理一个变化响应头。变化响应头在Apache 1.3 中是由mod_rewrite产生的。 其结果是MSIE会说不能下载请求的文件。更多细节信息请看PR#4118

一个解决办法是在服务器配置文件中添加:

BrowserMatch "MSIE 4\.0" force-no-vary

(此办法只适用Apache Web 服务器 1.3.6 之后的发布。)

 


项目维护者: kajaa [本文译者: suncjs * ]

项目说明 | 项目进度 | 项目讨论区 | Apache手册中文版