📄 content-negotiation.html
字号:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<meta name="keywords" content="Apache, 中文, 手册, 中文版, 中文手册, 中文版手册, 参考手册, 中文参考手册, 金步国" />
<meta name="description" content="Apache 2.2 中文版参考手册" />
<meta name="author" content="金步国" />
<link href="./style/css/manual-zip.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
<link href="./style/css/manual-zip-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
<link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" />
<title>内容协商 - Apache 2.2 中文版参考手册</title>
</head>
<body id="manual-page">
<div id="page-header"><p class="menu"><a href="./mod/index.html">模块索引</a> | <a href="./mod/directives.html">指令索引</a> | <a href="./faq/index.html">常见问题</a> | <a href="./glossary.html">词汇表</a> | <a href="./sitemap.html">站点导航</a></p><p class="apache">Apache HTTP Server 版本2.2</p><img alt="" src="./images/feather.gif" /></div>
<div class="up"><a href="./index.html"><img title="<-" alt="<-" src="./images/left.gif" /></a></div>
<div id="path"><a href="http://www.apache.org/">Apache</a> > <a href="http://httpd.apache.org/">HTTP Server</a> > <a href="http://httpd.apache.org/docs/">文档</a> > <a href="./index.html">版本2.2</a></div>
<div id="translation-info"> <a href="./translator_announcement.html#thanks">致谢</a> | <a href="./translator_announcement.html#announcement">译者声明</a> | 本篇译者:<a href="mailto:csfrank@citiz.net">金步国</a> | 本篇译稿最后更新:2006年1月2日 | <a href="./translator_announcement.html#last_new">获取最新版本</a></div>
<div id="page-content"><div id="preamble"><h1>内容协商</h1>
<p>Apache支持HTTP/1.1规范中定义的内容协商,它可以根据浏览器提供的参数选择一个资源最合适的媒体类型、语言、字符集和编码的表现方式。它还实现了一些对浏览器发送不完整内容协商信息进行智能处理的能力。</p>
<p>内容协商由<code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code>模块支持,并被默认编译进服务器。</p>
</div>
<div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
<div class="section">
<h2><a name="about" id="about">关于内容协商(Content Negotiation)</a></h2>
<p>一个资源可能会有多种不同的表现形式,比如,可能会有不同语言或者媒体类型的版本甚至其组合。最常用的选择方法是提供一个索引页以供选择。但是由于浏览器可以在请求头信息中提供其首选项的表现形式,因此就有可能让服务器进行自动选择。比如,浏览器可以表明希望看见法语的信息,如果没有,英语的也行。如需仅请求法语的表现形式,浏览器可以发出:</p>
<div class="example"><p><code>Accept-Language: fr</code></p></div>
<p>注意:此首选项信息仅当存在多种可选的语言表现形式时才有效。</p>
<p>下面是一个更复杂的请求,浏览器表明,可以接受法语和英语,但最好是法语;接受各种媒体类型,最好是HTML,但纯文件或其他文本类型也可以;最好是GIF或JPEG,但其他媒体类型也可以,并允许其他媒体类型作为最终表现形式:</p>
<div class="example"><p><code>
Accept-Language: fr; q=1.0, en; q=0.5<br />
Accept: text/html; q=1.0, text/*; q=0.8, image/gif; q=0.6, image/jpeg; q=0.6, image/*; q=0.5, */*; q=0.1
</code></p></div>
<p>Apache支持HTTP/1.1规范中定义的"服务器驱动"的内容协商, 可以完全地支持<code>Accept</code>、<code>Accept-Language</code>、<code>Accept-Charset</code>、<code>Accept-Encoding</code>请求头,这些是RFC2295和RFC2296中定义的实验协商协议,但是不支持这些RFC中定义的"功能协商"。</p>
<p><strong>资源(resource)</strong>是一个在URI(RFC2396)中定义的概念上的实体。一个HTTP服务器,比如Apache,以<strong>表现形式(representation)</strong>提供对其名称空间中资源的访问,各种表现形式由已定义的媒体类型、字符集和编码的字节流构成。任何一个特定的时刻,一个资源可以没有,或者有一个,或者有多个表现形式。如果有多个表现形式存在,则称该资源是<strong>可协商的(negotiable)</strong>,其各种表现形式称为<strong>变种(variant)</strong>。而一个可协商的资源的各种变种的区别途径称为<strong>变元(dimension)</strong>。</p>
</div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
<div class="section">
<h2><a name="negotiation" id="negotiation">Apache中的内容协商</a></h2>
<p>可以使用下述两种途径之一向服务器提供有关各变种的信息,以实现对资源的协商:</p>
<ul>
<li>使用类型表(也就是一个 <code>*.var</code>文件)明确指定各变种的文件名。</li>
<li>使用"MultiViews"搜索,即服务器执行一个隐含的文件名模式匹配,并在其结果中选择。</li>
</ul>
<h3><a name="type-map" id="type-map">使用类型表文件</a></h3>
<p>类型表是一个与<code>type-map</code>处理器关联的文档(或者兼容早期Apache配置的<a class="glossarylink" href="./glossary.html#mime-type" title="see glossary">MIME类型</a>:<code>application/x-type-map</code> )。要使用这个功能,必须在配置中建立处理器,以定义一个文件后缀为<code>type-map</code>,最好的方法是在配置文件中这样设置:</p>
<div class="example"><p><code>AddHandler type-map .var</code></p></div>
<p>类型表文件应该与所描述的资源同名,且对每个有效变种都有一个块(entry),每个块由若干连续的HTTP头行组成,不同变种的块用空行分开,块中不允许有空行。习惯上,类型表都以一个描述总体性质的组合块作为开始(这不是必须的,如果有也会被忽略)。下例是一个描述资源<code>foo</code>的命名为<code>foo.var</code>的类型表文件:</p>
<div class="example"><p><code>
URI: foo<br />
<br />
URI: foo.en.html<br />
Content-type: text/html<br />
Content-language: en<br />
<br />
URI: foo.fr.de.html<br />
Content-type: text/html;charset=iso-8859-2<br />
Content-language: fr, de<br />
</code></p></div>
<p>注意:即使将<code>MultiViews</code>设置为 <code>On</code> ,类型表仍然优先于文件后缀名。如果不同的变种具有不同的资源品质,就可以对媒体类型使用"qs"参数来表示这种不同。下例演示了一个图片的 jpeg, gif, ASCII-art 三个有效变种:</p>
<div class="example"><p><code>
URI: foo<br />
<br />
URI: foo.jpeg<br />
Content-type: image/jpeg; qs=0.8<br />
<br />
URI: foo.gif<br />
Content-type: image/gif; qs=0.5<br />
<br />
URI: foo.txt<br />
Content-type: text/plain; qs=0.01<br />
</code></p></div>
<p>qs的取值范围是0.000到1.000,取值为0.000的变种永远不会被选择,没有指定qs值的变种其qs值为1.0。qs值表示一个变种相对于其他变种的"品质",比如在表现一张照片时,jpeg通常比字符构图有更高的品质;而如果要表现的本来就是一个ASCII-art ,那么当然字符构图就会比jpeg文件有更高的品质。因此,qs的值取决于变种所表现的资源本身。</p>
<p><a href="mod/mod_negotiation.html#typemaps">mod_negotation类型表</a>文档中有完整的HTTP头的列表。</p>
<h3><a name="multiviews" id="multiviews">Multiviews</a></h3>
<p><code>MultiViews</code>是一个针对每个目录的选项,也就是说可以在<code>httpd.conf</code>或<code>.htaccess</code>(如果正确设置了<code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code>)文件中的<code class="directive"><a href="./mod/core.html#directory"><Directory></a></code>、<code class="directive"><a href="./mod/core.html#location"><Location></a></code>、<code class="directive"><a href="./mod/core.html#files"><Files></a></code>配置段中,用<code class="directive"><a href="./mod/core.html#options">Options</a></code>指令来指定。注意,<code>Options All</code> 并不会设置<code>MultiViews</code> ,你必须明确地指定。</p>
<p><code>MultiViews</code>的效果是:如果服务器收到对<code>/some/dir/foo</code>的请求,而<code>/some/dir/foo</code>并<em>不</em>存在,但是如果<code>/some/dir</code>启用了<code>MultiViews</code> ,则服务器会查找这个目录下所有的foo.* 文件,并有效地伪造一个说明这些foo.* 文件的类型表,分配给他们相同的媒体类型及内容编码,并选择其中最合适的匹配返回给客户。</p>
<p><code>MultiViews</code>还可以在服务器检索一个目录时,用于<code class="directive"><a href="./mod/mod_dir.html#directoryindex">DirectoryIndex</a></code>指令搜索的文件名。如果设置了:</p>
<div class="example"><p><code>DirectoryIndex index</code></p></div>
<p>而<code>index.html</code>和<code>index.html3</code>并存,则服务器会作一个权衡;如果都没有,但是有<code>index.cgi</code> ,则服务器会执行它。</p>
<p>如果一个目录中没有任何文件具有<code>mod_mime</code>可以识别的表示其字符集、内容类型、语言和编码的后缀,那么其结果将取决于<code class="directive"><a href="./mod/mod_mime.html#multiviewsmatch">MultiViewsMatch</a></code>指令的设置,这个指令决定了在MultiViews协商中将使用的处理器、过滤器和其他后缀类型。</p>
</div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
<div class="section">
<h2><a name="methods" id="methods">协商的方法</a></h2>
<p>Apache从一个类型表或者某个目录的文件名中得到一个资源变种列表以后,会使用两种方法之一选择可能的"最佳"变种返回给客户。使用Apache的内容协商功能并不需要了解其细节,以下文档对这些方法加以详细说明,供有兴趣的人看看。</p>
<p>协商有两种方法:</p>
<ol>
<li><strong>使用Apache算法的服务器驱动协商</strong> 是通常情况下的默认方法。使用这个算法(下面有详细的描述),为了得到更好的效果,Apache有时会"打乱"一个特定变元(dimension)的品质因子,其方法稍后会详细阐述。</li>
<li><strong>透明内容协商</strong> 仅当浏览器明确地用RFC2295中定义的机制发出请求时才使用。这种方法可以给予浏览器对"最佳"变种选择的完全控制,因此其效果也取决于浏览器使用的算法。作为透明协商过程的一部分,浏览器可以要求Apache执行RFC2296中定义的"远程变种选择算法"。</li>
</ol>
<h3><a name="dimensions" id="dimensions">协商的变元(Dimension)</a></h3>
<table border="1" cellpadding="0" cellspacing="0" bordercolor="#AAAAAA">
<tr valign="top"><th>变元</th><th>说明</th></tr>
<tr valign="top"><td>媒体类型</td><td>浏览器在<code>Accept</code>头中指明首选项,其中各项与品质因子关联,变种描述也可以有品质因子(参数"qs")。</td></tr>
<tr valign="top"><td>语言</td><td>浏览器在<code>Accept-Language</code>头中指明首选项,其中各项与品质因子关联,变种可以与零个、一个或多个语言关联。</td></tr>
<tr valign="top"><td>编码</td><td>浏览器在<code>Accept-Encoding</code>头中指明首选项,其中各项与品质因子关联。</td></tr>
<tr valign="top"><td>字符集</td><td>浏览器在<code>Accept-Charset</code>头中指明首选项,其中各项与品质因子关联,变种可以指定一个字符集作为媒体类型的一个参数。</td></tr>
</table>
<h3><a name="algorithm" id="algorithm">Apache协商算法</a></h3>
<p>Apache使用下述算法选择可能的"最佳"变种返回给浏览器。此算法不能被再配置。其过程如下:</p>
<ol>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -