热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

关于内容协商(ContentNegotiation)

关于内容协商(ContentNegotiation)--Linux企业应用-Linux服务器应用信息,下面是详情阅读。
内容协商

Apache支持HTTP/1.1规范中定义的内容协商,它可以根据浏览器提供的参数选择一个资源最合适的媒体类型、语言、字符集和编码的表现方式。它还实现了一些对浏览器发送不完整内容协商信息进行智能处理的能力。

内容协商由mod_negotiation模块支持,并被默认编译进服务器。
top
关于内容协商(Content Negotiation)

一个资源可能会有多种不同的表现形式,比如,可能会有不同语言或者媒体类型的版本甚至其组合。最常用的选择方法是提供一个索引页以供选择。但是由于浏览器可以在请求头信息中提供其首选项的表现形式,因此就有可能让服务器进行自动选择。比如,浏览器可以表明希望看见法语的信息,如果没有,英语的也行。如需仅请求法语的表现形式,浏览器可以发出:

Accept-Language: fr

注意:此首选项信息仅当存在多种可选的语言表现形式时才有效。

下面是一个更复杂的请求,浏览器表明,可以接受法语和英语,但最好是法语;接受各种媒体类型,最好是HTML,但纯文件或其他文本类型也可以;最好是GIF或JPEG,但其他媒体类型也可以,并允许其他媒体类型作为最终表现形式:

Accept-Language: fr; q=1.0, en; q=0.5
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

Apache支持HTTP/1.1规范中定义的"服务器驱动"的内容协商, 可以完全地支持Accept、Accept-Language、Accept-Charset、Accept-Encoding请求头,这些是RFC2295和RFC2296中定义的实验协商协议,但是不支持这些RFC中定义的"功能协商"。

资源(resource)是一个在URI(RFC2396)中定义的概念上的实体。一个HTTP服务器,比如Apache,以表现形式(representation)提供对其名称空间中资源的访问,各种表现形式由已定义的媒体类型、字符集和编码的字节流构成。任何一个特定的时刻,一个资源可以没有,或者有一个,或者有多个表现形式。如果有多个表现形式存在,则称该资源是可协商的(negotiable),其各种表现形式称为变种(variant)。而一个可协商的资源的各种变种的区别途径称为变元(dimension)。
top
Apache中的内容协商

可以使用下述两种途径之一向服务器提供有关各变种的信息,以实现对资源的协商:

* 使用类型表(也就是一个 *.var文件)明确指定各变种的文件名。
* 使用"MultiViews"搜索,即服务器执行一个隐含的文件名模式匹配,并在其结果中选择。

使用类型表文件

类型表是一个与type-map处理器关联的文档(或者兼容早期Apache配置的MIME类型:application/x-type-map )。要使用这个功能,必须在配置中建立处理器,以定义一个文件后缀为type-map,最好的方法是在配置文件中这样设置:

AddHandler type-map .var

类型表文件应该与所描述的资源同名,且对每个有效变种都有一个块(entry),每个块由若干连续的HTTP头行组成,不同变种的块用空行分开,块中不允许有空行。习惯上,类型表都以一个描述总体性质的组合块作为开始(这不是必须的,如果有也会被忽略)。下例是一个描述资源foo的命名为foo.var的类型表文件:

URI: foo

URI: foo.en.html
Content-type: text/html
Content-language: en

URI: foo.fr.de.html
Content-type: text/html;charset=iso-8859-2
Content-language: fr, de

注意:即使将MultiViews设置为 On ,类型表仍然优先于文件后缀名。如果不同的变种具有不同的资源品质,就可以对媒体类型使用"qs"参数来表示这种不同。下例演示了一个图片的 jpeg, gif, ASCII-art 三个有效变种:

URI: foo

URI: foo.jpeg
Content-type: image/jpeg; qs=0.8

URI: foo.gif
Content-type: image/gif; qs=0.5

URI: foo.txt
Content-type: text/plain; qs=0.01

qs的取值范围是0.000到1.000,取值为0.000的变种永远不会被选择,没有指定 qs值的变种其qs值为1.0。qs值表示一个变种相对于其他变种的"品质",比如在表现一张照片时,jpeg通常比字符构图有更高的品质;而如果要表现的本来就是一个ASCII-art ,那么当然字符构图就会比jpeg文件有更高的品质。因此,qs的值取决于变种所表现的资源本身。

mod_negotation类型表文档中有完整的HTTP头的列表。
Multiviews

MultiViews是一个针对每个目录的选项,也就是说可以在httpd.conf或.htaccess(如果正确设置了AllowOverride)文件中的配置段中,用Options指令来指定。注意,Options All 并不会设置MultiViews ,你必须明确地指定。

MultiViews的效果是:如果服务器收到对/some/dir/foo的请求,而/some/dir/foo并不存在,但是如果/some/dir启用了MultiViews ,则服务器会查找这个目录下所有的foo.* 文件,并有效地伪造一个说明这些foo.* 文件的类型表,分配给他们相同的媒体类型及内容编码,并选择其中最合适的匹配返回给客户。

MultiViews还可以在服务器检索一个目录时,用于DirectoryIndex指令搜索的文件名。如果设置了:

DirectoryIndex index

而index.html和index.html3并存,则服务器会作一个权衡;如果都没有,但是有index.cgi ,则服务器会执行它。

如果一个目录中没有任何文件具有mod_mime可以识别的表示其字符集、内容类型、语言和编码的后缀,那么其结果将取决于MultiViewsMatch指令的设置,这个指令决定了在MultiViews协商中将使用的处理器、过滤器和其他后缀类型。
top
协商的方法

Apache从一个类型表或者某个目录的文件名中得到一个资源变种列表以后,会使用两种方法之一选择可能的"最佳"变种返回给客户。使用Apache的内容协商功能并不需要了解其细节,以下文档对这些方法加以详细说明,供有兴趣的人看看。

协商有两种方法:

1. 使用Apache算法的服务器驱动协商 是通常情况下的默认方法。使用这个算法(下面有详细的描述),为了得到更好的效果,Apache有时会"打乱"一个特定变元(dimension)的品质因子,其方法稍后会详细阐述。
2. 透明内容协商 仅当浏览器明确地用RFC2295中定义的机制发出请求时才使用。这种方法可以给予浏览器对"最佳"变种选择的完全控制,因此其效果也取决于浏览器使用的算法。作为透明协商过程的一部分,浏览器可以要求Apache执行RFC2296中定义的"远程变种选择算法"。

协商的变元(Dimension)
变元 说明
媒体类型 浏览器在Accept头中指明首选项,其中各项与品质因子关联,变种描述也可以有品质因子(参数"qs")。
语言 浏览器在Accept-Language头中指明首选项,其中各项与品质因子关联,变种可以与零个、一个或多个语言关联。
编码 浏览器在Accept-Encoding头中指明首选项,其中各项与品质因子关联。
字符集 浏览器在Accept-Charset头中指明首选项,其中各项与品质因子关联,变种可以指定一个字符集作为媒体类型的一个参数。
Apache协商算法

Apache使用下述算法选择可能的"最佳"变种返回给浏览器。此算法不能被再配置。其过程如下:

1. 首先,对每个协商变元,检查其适当的Accept* 头,并对每个变种指定一个品质。如果一个变元的Accept* 头指示不接受这个变种,则被剔除。如果最终没有变种了,则转到步骤4。
2. 顺序执行以下的测试,使用逐步剔除的方法来选择"最佳"变种。不能通过测试的变种将被剔除。每个测试完成后,如果仅剩一个变种,则作为最佳匹配,转到步骤3;如果多于一个,则继续下一个测试。
1. 将Accept头的品质因子乘以该变种媒体类型的还原品质因子,选择乘积最高者。
2. 选择语言品质因子最高的变种。
3. 使用Accept-Language头中的语言顺序(如果存在的话),或者使用LanguagePriority指令中的语言顺序(如果存在的话)选择最匹配的语言。
4. 选择最高"等级"媒体参数的变种(用以确定text/html的媒体类型)。
5. 选择Accept-Charset头中指定的最佳字符集媒体参数的变种。如果没有明确指定,则使用ISO-8859-1字符集。具有text/* 媒体类型而没有明确地与一个特定字符集关联的变种,将使用ISO-8859-1。
6. 选择与之关联字符集不是ISO-8859-1的变种,如果没有这样的变种,则选择所有的变种。
7. 选择最佳编码的变种。如果存在用户代理可以接受的编码的变种,则选择之;否则,如果存在混合编码的或者未编码的变种,则选择未编码的变种。如果所有的变种都是编码的,或者所有变种都是未编码的,则选择所有的变种。
8. 选择内容长度最小的变种。
9. 选择剩余变种的最前一个,这个变种或是类型表文件中的第一个,或从目录中读取变种被时,以ASCII编码顺序的第一个文件。
3. 这时,此算法已经选择了一个"最佳"变种,并将之返回作为响应。HTTP响应头的Vary会指明协商的变元(浏览器和缓存可以利用此信息缓存该资源)。
4. 如果没有一个变种被选择(因为没有一种可以被浏览器接受),则返回一个状态值为406响应体,并包含一个HTML格式的有效变种列表,同样,在HTTP头的Vary中指明了变种的变元。

top
打乱品质值

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

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

Accept: image/*, */*

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

Accept: text/html, text/plain, image/gif, image/jpeg, */*

其目的是表明,明确列出的是首选项,其他不同的表现也可以。这种用法不是不可以,但是"*/*"其实可以通配所有其他类型,所以不推荐这样用,而应该对"*.*"赋予一个较低的品质(首选)值0.01,如:

Accept: text/html, text/plain, image/gif, image/jpeg, */*; q=0.01

明确指定的类型没有品质值,所以其品质值是默认的最高值1.0,而"*/*"是较低的0.01,所以,只有在没有匹配明确指定类型的变种时,才会返回其他类型。

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

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

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

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

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

SetEnvIf COOKIE "language=(.+)" prefer-language=$1
top
透明内容协商的扩展

Apache在变种列表中使用了一个新的{encoding ..}元素来标记变种,从而扩展了透明内容协商协议(RFC2295)。实现RVSA/1.0算法(RFC2296)的目的是识别列表中被编码的变种,作为可以被Accept-Encoding请求头接受的候选变种。在选择最佳变种之前,RVSA/1.0的实现不会对品质因子作四舍五入的运算。
top
超链和名称转换说明

如果使用语言协商,由于文件可以有不止一个后缀,因此就可以选择不同的名称转换,其后缀顺序通常是无关紧要的(参见mod_mime文档)。

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

例如:

* foo.en.html
* foo.html.en
* foo.en.html.gz

文件名和有效及无效超链的例子:
文件名 有效超链 无效超链
foo.html.en foo
foo.html -
foo.en.html foo foo.html
foo.html.en.gz foo
foo.html foo.gz
foo.html.gz
foo.en.html.gz foo foo.html
foo.html.gz
foo.gz
foo.gz.html.en foo
foo.gz
foo.gz.html foo.html
foo.html.gz.en foo
foo.html
foo.html.gz foo.gz

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

如果希望在超链中继续使用MIME类型(如foo.html),则语言后缀(还包括一个编码后缀)必须出现在MIME类型后缀的右边(如foo.html.en)。
top
缓冲说明

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

对来自HTTP/1.0客户端的请求(浏览器或缓存),CacheNegotiatedDocs指令可以允许缓存服从协商的请求。此指令应该出现在主服务器或虚拟主机的配置中,没有参数,并且对来自HTTP/1.1客户端的请求没有影响。

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

更多有关内容协商的信息,可以参见Alan J. Flavell的Language Negotiation Notes,但是注意,此文档可能没有升级以包含Apache2.0中的改变。
推荐阅读
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 阿里Treebased Deep Match(TDM) 学习笔记及技术发展回顾
    本文介绍了阿里Treebased Deep Match(TDM)的学习笔记,同时回顾了工业界技术发展的几代演进。从基于统计的启发式规则方法到基于内积模型的向量检索方法,再到引入复杂深度学习模型的下一代匹配技术。文章详细解释了基于统计的启发式规则方法和基于内积模型的向量检索方法的原理和应用,并介绍了TDM的背景和优势。最后,文章提到了向量距离和基于向量聚类的索引结构对于加速匹配效率的作用。本文对于理解TDM的学习过程和了解匹配技术的发展具有重要意义。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 生成对抗式网络GAN及其衍生CGAN、DCGAN、WGAN、LSGAN、BEGAN介绍
    一、GAN原理介绍学习GAN的第一篇论文当然由是IanGoodfellow于2014年发表的GenerativeAdversarialNetworks(论文下载链接arxiv:[h ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 推荐系统遇上深度学习(十七)详解推荐系统中的常用评测指标
    原创:石晓文小小挖掘机2018-06-18笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值, ... [详细]
author-avatar
秋天的紫丁香
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有