⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 content-negotiation.html

📁 这个是我在web培训时老师提供的手册
💻 HTML
📖 第 1 页 / 共 2 页
字号:
      <li>首先,对每个协商变元,检查其适当的<em>Accept*</em> 头,并对每个变种指定一个品质。如果一个变元的<em>Accept*</em> 头指示不接受这个变种,则被剔除。如果最终没有变种了,则转到步骤4。</li>

      <li>顺序执行以下的测试,使用逐步剔除的方法来选择"最佳"变种。不能通过测试的变种将被剔除。每个测试完成后,如果仅剩一个变种,则作为最佳匹配,转到步骤3;如果多于一个,则继续下一个测试。

        <ol>
          <li>将<code>Accept</code>头的品质因子乘以该变种媒体类型的还原品质因子,选择乘积最高者。</li>

          <li>选择语言品质因子最高的变种。</li>

          <li>使用<code>Accept-Language</code>头中的语言顺序(如果存在的话),或者使用<code>LanguagePriority</code>指令中的语言顺序(如果存在的话)选择最匹配的语言。</li>

          <li>选择最高"等级"媒体参数的变种(用以确定text/html的媒体类型)。</li>

          <li>选择<code>Accept-Charset</code>头中指定的最佳字符集媒体参数的变种。如果没有明确指定,则使用ISO-8859-1字符集。具有<code>text/*</code> 媒体类型而没有明确地与一个特定字符集关联的变种,将使用ISO-8859-1。</li>

          <li>选择与之关联字符集<em>不是</em>ISO-8859-1的变种,如果没有这样的变种,则选择所有的变种。</li>

          <li>选择最佳编码的变种。如果存在用户代理可以接受的编码的变种,则选择之;否则,如果存在混合编码的或者未编码的变种,则选择未编码的变种。如果所有的变种都是编码的,或者所有变种都是未编码的,则选择所有的变种。</li>

          <li>选择内容长度最小的变种。</li>

          <li>选择剩余变种的最前一个,这个变种或是类型表文件中的第一个,或从目录中读取变种被时,以ASCII编码顺序的第一个文件。</li>
        </ol>
      </li>

      <li>这时,此算法已经选择了一个"最佳"变种,并将之返回作为响应。HTTP响应头的<code>Vary</code>会指明协商的变元(浏览器和缓存可以利用此信息缓存该资源)。</li>

      <li>如果没有一个变种被选择(因为没有一种可以被浏览器接受),则返回一个状态值为406响应体,并包含一个HTML格式的有效变种列表,同样,在HTTP头的<code>Vary</code>中指明了变种的变元。</li>
    </ol>

</div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
<div class="section">
<h2><a name="better" id="better">打乱品质值</a></h2>

    <p>Apache有时会改变按照Apache协商算法应该被严格解析的品质值,从而在浏览器没有发送完整的精确的信息时获得更好的效果。有些很常用的浏览器在许多情况下,会发送导致变种选择错误的<code>Accept</code>头信息。如果一个浏览器发送了完整的且正确的信息,则不会有打乱操作。</p>

<h3><a name="wildcards" id="wildcards">媒体类型与通配符</a></h3>

   <p><code>Accept:</code> 请求头指明了媒体类型的首选项,也可以包含"通配"媒体类型,如"image/*"和匹配任何字符串的"*/*"。所以,如果一个请求包含:</p>

<div class="example"><p><code>Accept: image/*, */*</code></p></div>

   <p>会指明可以接受任何以"image/"开头的类型,和其他任何类型(因而前面的"image/*"就是多余的)。有些浏览器就会这样例行公事地在明确指定允许的类型后面附加通配类型,比如:</p>

<div class="example"><p><code>
  Accept: text/html, text/plain, image/gif, image/jpeg, */*
</code></p></div>
   <p>其目的是表明,明确列出的是首选项,其他不同的表现也可以。这种用法不是不可以,但是"*/*"其实可以通配所有其他类型,所以不推荐这样用,而应该对"*.*"赋予一个较低的品质(首选)值0.01,如:</p>
<div class="example"><p><code>
  Accept: text/html, text/plain, image/gif, image/jpeg, */*; q=0.01
</code></p></div>
   <p>明确指定的类型没有品质值,所以其品质值是默认的最高值1.0,而"*/*"是较低的0.01,所以,只有在没有匹配明确指定类型的变种时,才会返回其他类型。</p>

   <p>如果<code>Accept:</code> 头<em>没有</em>指定任何q因子,那么Apache设置"*/*"的q值为0.01来模拟上述推荐的行为,还会设置"type/*"的q值为0.02,使之优先于"*/*"。如果<code>Accept:</code> 头中任何媒体类型指定了q因子,则<em>不会</em>使用这些特殊值,以使正确发送信息的浏览器能正常运作。</p>


	<h3><a name="exceptions" id="exceptions">语言协商的例外</a></h3>

   <p>在Apache 2.0中的协商算法中,新增了一些例外的规则,以允许在语言协商匹配失败的情况下,作巧妙的妥协。</p>

   <p>通常,当客户端向服务器请求一个不能与浏览器<code>Accept-language</code>所匹配的唯一的页面时,服务器会返回一个"No Acceptable Variant" 或者 "Multiple Choices" 响应。但是,有可能通过配置Apache,忽略这些情况下的<code>Accept-language</code> ,而返回一个不是非常匹配客户请求的文本,以避免这些错误信息的出现。<code class="directive"><a href="./mod/mod_negotiation.html#forcelanguagepriority">ForceLanguagePriority</a></code>指令可以屏蔽这两种错误信息,并接管由<code class="directive"><a href="./mod/mod_negotiation.html#languagepriority">LanguagePriority</a></code>指令控制的服务器裁定机制。</p>

   <p>服务器还会在匹配失败时尝试用语言子集来匹配。例如,如果一个客户请求了一个语言是<code>en-GB</code>的英国英语的页面,而服务器只支持HTTP/1.1标准的简单的<code>en</code> 。(注意,在<code>Accept-Language</code>中指定<code>en-GB</code>而不是<code>en</code>几乎绝对是个错误,因为它似乎暗示阅读的人懂英国英语却不懂大众英语。而不幸的是,许多流行的客户端的默认配置却是这样的)。如果没有可以匹配的语言,服务器将会忽略其语言子集的设定,返回"No Acceptable Variants"错误,或者按<code class="directive"><a href="./mod/mod_negotiation.html#languagepriority">LanguagePriority</a></code>指令作妥协。Apache会隐含地在客户可接受语言的列表中附加一个具有很低品质值的父语言,但是,如果客户请求"en-GB; q=0.9, fr; q=0.8" 那么将返回"fr"的文本,这对遵循HTTP/1.1标准以使正确配置的浏览器能正常工作是必须的。</p>

   <p>为了支持用于确定用户首选语言的高级技术(比如cookies或特殊的URL路径),从2.0.47版本起<code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code>模块开始支持<code>prefer-language</code><a href="env.html">环境变量</a>。如果存在并且包含一个语言标签,<code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code>模块将会尝试选择一个匹配的变种。如果不存在这样的变种,将会使用上述通常的协商过程。</p>

   <div class="example"><h3>示例</h3><p><code>
      SetEnvIf Cookie "language=(.+)" prefer-language=$1
   </code></p></div>

</div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
<div class="section">
<h2><a name="extensions" id="extensions">透明内容协商的扩展</a></h2> 

<p>Apache在变种列表中使用了一个新的<code>{encoding ..}</code>元素来标记变种,从而扩展了透明内容协商协议(RFC2295)。实现RVSA/1.0算法(RFC2296)的目的是识别列表中被编码的变种,作为可以被<code>Accept-Encoding</code>请求头接受的候选变种。在选择最佳变种之前,RVSA/1.0的实现不会对品质因子作四舍五入的运算。</p>
</div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
<div class="section">
<h2><a name="naming" id="naming">超链和名称转换说明</a></h2>

   <p>如果使用语言协商,由于文件可以有不止一个后缀,因此就可以选择不同的名称转换,其后缀顺序通常是无关紧要的(参见<a href="mod/mod_mime.html#multipleext">mod_mime</a>文档)。</p>

   <p>一个典型的有MIME类型后缀的文件(如<code>html</code>),其后缀可以是编码后缀(如<code>gz</code>),也可以是语言变种后缀(如<code>en</code>)</p>

   <p>例如:</p>

   <ul>
     <li>foo.en.html</li>

     <li>foo.html.en</li>

     <li>foo.en.html.gz</li>
   </ul>

   <p>文件名和有效及无效超链的例子:</p>

   <table border="1" cellpadding="0" cellspacing="0" bordercolor="#AAAAAA" class="bordered">
<tr><th>文件名</th><th>有效超链</th><th>无效超链</th></tr>
<tr><td><em>foo.html.en</em></td><td>foo<br />
         foo.html</td><td>-</td></tr>
<tr><td><em>foo.en.html</em></td><td>foo</td><td>foo.html</td></tr>
<tr><td><em>foo.html.en.gz</em></td><td>foo<br />
         foo.html</td><td>foo.gz<br />
         foo.html.gz</td></tr>
<tr><td><em>foo.en.html.gz</em></td><td>foo</td><td>foo.html<br />
         foo.html.gz<br />
         foo.gz</td></tr>
<tr><td><em>foo.gz.html.en</em></td><td>foo<br />
         foo.gz<br />
         foo.gz.html</td><td>foo.html</td></tr>
<tr><td><em>foo.html.gz.en</em></td><td>foo<br />
         foo.html<br />
         foo.html.gz</td><td>foo.gz</td></tr>
</table>

   <p>可以看出,上表中使用没有任何后缀的超链(如<code>foo</code>)总是可行的,其优点是可以隐藏rsp. 文件的真实类型,而可以在将来作更改,比如,不用修改超链本身,而改变<code>html</code>为<code>shtml</code>或<code>cgi</code>  。</p>

   <p>如果希望在超链中继续使用MIME类型(如<code>foo.html</code>),则语言后缀(还包括一个编码后缀)必须出现在MIME类型后缀的右边(如<code>foo.html.en</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="caching" id="caching">缓冲说明</a></h2>

   <p>如果缓存中有一个与特定URL关联的表现形式(representation),那么下一次该URL被请求时,缓存就可以使用它。但是,如果这个资源在服务器端是可协商的,则可能只有第一次请求的变种是正确的,而其后由于缓存中命中而取出的结果是错误的。为避免这种情况的发生,Apache通常把内容协商之后返回的响应标记为不可以被HTTP/1.1客户端缓冲。另外Apache还支持HTTP/1.1协议的功能以允许缓冲已协商的请求。</p>

   <p>对来自HTTP/1.0客户端的请求(浏览器或缓存),<code class="directive"><a href="./mod/mod_negotiation.html#cachenegotiateddocs">CacheNegotiatedDocs</a></code>指令可以允许缓存服从协商的请求。此指令应该出现在主服务器或虚拟主机的配置中,没有参数,并且对来自HTTP/1.1客户端的请求没有影响。</p>

   <p>对于遵守HTTP/1.1规范的客户端,Apache发送一个<code>Vary</code>应答头以指定该应答的协商变元。缓存可以使用这个信息来判断一个其后的请求是否可以从本地副本中提供服务。为了鼓励缓存使用本地副本而不是协商变元,请设置<code>force-no-vary</code><a href="env.html#special">环境变量</a>。</p>

</div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
<div class="section">
<h2><a name="more" id="more">更多信息</a></h2>

   <p>更多有关内容协商的信息,可以参见Alan J. Flavell的<a href="http://ppewww.ph.gla.ac.uk/~flavell/www/lang-neg.html">Language Negotiation Notes</a>,但是注意,此文档可能没有升级以包含Apache2.0中的改变。</p>
</div></div>
<div id="footer">
<p class="apache">本文允许自由使用、分发、转载,但必须保留译者署名;详见:<a href="./translator_announcement.html#announcement">译者声明</a>。</p>
<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></div>
</body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -