Oh!Coder

Coding Life

读《HTTP权威指南》笔记(四)

| Comments

本书的第四部分讲解的主题为:实体、编码和国际化。这部分包括了三章内容。第十五章讲述了HTTP内容的格式和语法。第十六章探讨了允许世界各地的人们相互交换内容的各种Web标准,这些内容由各种不同语言和不同字符集构成。第十七章讲解了各种用于协商可接受内容的机制。下面,分别根据每章的具体内容,做一些摘录。

第十五章:实体和编码

总体来说,这一章讲解的知识点比较零碎。

报文是箱子,实体是货物

如果把HTTP报文想象成因特网货运系统中的箱子,那么HTTP实体就是报文中实际的货物。

HTTP实体首部描述了HTTP报文的内容。HTTP/1.1版定义了以下10个基本字体首部字段。
* Content-Type
实体中所承载对象的类型。
* Content-Length
所传送实体主体的长度或大小。
* Content-Language
与所传送对象最相配的人类语言。
* Content-Encoding
对象数据所做的任意变换(比如,压缩)。
* Content-Location
一个备用位置,请求时可通过它获得对象。
* Content-Range
如果这是部分实体,这个首部说明它是整体的哪个部分。
* Content-MD5
实体主体内容的校验和。
* Last-Modified
所传输内容在服务器上创建或最后修改的日期时间。
* Expires
实体数据将要失效的日期时间。
* Allow
该资源所允许的各种请求方法,例如,GETHEAD
* ETag
这份文档特定实例的唯一验证码。ETag首部没有正式定义为实体首部,但它对许多涉及实体的操作来说,都是一个重要的首部。
* Cache-Control
指出应该如何缓存该文档。和ETag首部类似,Cache-Control首部也没有正式为实体首部。

实体主体(Page.360)

实体主体就是原始货物。任何其他描述性的信息都包含在首部中。因为货物(也就是实体主体)只是原始数据,所以需要实体首部来描述数据的意义。

Content-Length:实体的大小(Page.361)

Content-Length首部指示出报文中实体主体的字节大小。这个大小是包含了所有内容编码的,比如,对文本文件进行了gzip压缩的话,Content-Length首部就是压缩后的大小,而不是原始大小。

内容编码(Page.362)

HTTP允许对实体主体的内容进行编码,比如可以使之更安全或进行压缩以节省空间。如果主体进行了内容编码,Content-Length首部说明的就是编码后(encoded)的主体的字节长度,而不是未编码的原始主体的长度。

确定实体主体长度的规则(Page.362~Page.363)
  1. 如果特定的HTTP报文类型中不允许带有主体,就忽略Content-Length首部,它是对(没有实际发送出来的)主体进行计算的。这种情况下,Content-Length首部是提示性的,并不说明实际的主体长度。

  2. 如果报文中含有描述传输编码的Transfer-Encoding首部(不采用默认的HTTP“恒等”编码),那实体就应由一个称为“零字节块”(zero-byte chunk)的特殊模式结束,除非报文已经因连接关闭而结束。

  3. 如果报文中含有Content-Length首部(并且报文类型允许有实体主体),而且没有非恒等的Transfer-Encoding首部字段,那么Content-Length的值就是主体的长度。
  4. 如果报文使用了multipart/byterages(多部分/字节范围)媒体类型,并且没有用Content-Length首部指出实体主体的长度,那么多部分报文中的每个部分都要说明它自己的大小。

  5. 如果上面的规则都不匹配,实体就在连接关闭的时候结束。
媒体类型和字符集(Page.364)

Content-Type首部字段说明了实体主体的MIME类型。MIME类型是标准化的名字,用以说明作为货物运载实体的基本媒体类型。客户端应用程序使用MIME类型来解释和处理其内容。其中,MIME类型由一个主媒体类型后面跟一条斜线以及一个子类型组成,子类型用于进一步描述媒体类型。

多部分媒体类型(Page.365)

MIME中的multipart(多部分)电子邮件报文中包含多个报文,它们合在一起作为单一的复杂报文发送。HTTP也支持多部分主体。不过通常只用在下列两种情形之一:提交填写好的表格,或是作为承载若干文档片段的范围响应。

内容编码过程(Page.368)

(1)网站服务器生成原始响应报文,其中有原始的Content-Type和Content-Length首部。
(2)内容编码服务器(也可能就是原始的服务器或下行的代理)创建编码后的报文。
(3)接收程序得到编码后的报文,进行编码,获得原始报文。

传输编码(Page.371)

传输编码也是作用在实体主体上的可逆变换,但使用它们是由于架构方面的原因,同内容的格式无关。

Transfer-Encoding首部(Page.372)
  • Transfer-Encoding
    告知接收方为了可靠地传输报文,已经对其进行了何种编码。

  • TE
    用在请求首部中,告知服务器可以使用哪些传输编码扩展。

分块编码(Page.373)

分块编码把报文分割为若干个大小已知地块,块之间是紧挨着的,这样就不需要在发送之前知道整个报文地大小了。

要注意地是,分块编码是一种传输编码,因此是报文的属性,而不是主体的属性。

  1. 分块与持久连接
    若客户端和服务器之间不是持久连接,客户端就不需要知道它正在读取的主体的长度,而只需要读到服务器关闭主体连接为止。
  2. 分块报文的拖挂
    如果客户端的TE首部中说明它可以接收拖挂的话,就可以在分块的报文最后加上拖挂。

内容编码和传输编码可以同时使用。

传输编码的规则(Page.375)
  • 传输编码集合中必须包括“分块”。唯一的例外是使用关闭连接来结束报文。
  • 当使用分块传输编码时,它必须是最后一个作用到报文主体之上的。
  • 分块传输编码不能多次作用到一个报文主体上。
随时间变化的实例(Page.376)

HTTP协议规定了称为实例操控(instance manipulations)的一系列请求和响应操作,用以操控对象的实例。两个主要的实例操控方法是范围请求和差异编码。

新鲜度(Page.377)

服务器应当告知客户端能够将内容缓存多长时间,在这个时间之内就是新鲜的。服务器可以用这两个首部之一来提供这种信息:Expires(过期)和Cache-Control(缓存控制)。

有条件请求(Page.378)

有条件的请求是标准的HTTP请求报文,但仅当某个特定条件为真时才执行。

验证码(Page.378)

验证码是文档实例的一个特殊属性,用它来测试条件是否为真。HTTP把验证码分为两类:弱验证码(weak validators)和强验证码(strong validators)。弱验证码不一定能唯一标识资源的一个实例,而强验证码必须如此。

第十六章:国际化

本章在国际化方面包括两个问题:字符集编码(character set encoding)和语言标记(language tag)。

服务器通过HTTP协议的Content-Type首部中的charset参数和Content-Language首部告知客户端文档的字母表和语言。HTTP字符集的值说明如何把实体内容的二进制码转换为特定字母表中的字符。

国际化字符系统的关键目标是把语义(字母)和表示(图形化的显示形状)隔离开来。HTTP只关心字符数据和相关语言及字符集标签的传输。字符形状的显示是由用户的图形显示软件完成的。

特定的字符编码方案和特定的已编码字符集组合成一个MIME字符集(MIME charst)。HTTP在Content-Type和Accept-Charset首部中使用标准化的MIME charset标记。

Web服务器通过在Content-Type首部中使用charset参数把MIME字符集标记发送给客户端:

Conent-Type: text/html; charset=iso-2022-jp

HTTP客户端可以使用Accept-Charset请求首部来明确告知服务器它支持哪些字符系统。

字符集术语(Page.394)

  • 字符
    字符是指字母、数字、标点、表意文字(比如汉语)、符号,或其他文本形式的书写“原子”。

  • 字形
    描述字符的笔画图案或唯一的图形化形状。

  • 编码后的字符
    分配给字符的唯一数字编号,这样我们就可以操作它了。

  • 代码空间
    计划用于字符代码值的整数范围。

  • 代码宽度
    每个(固定大小的)字符代码所用的位数。

  • 字符库
    特定的工作字符集(全体字符的一个子集)。

  • 编码后的字符集
    组成字符库(从全球的字符中选出若干字符)的已编码字符集,并为每个字符分配代码空间中的一个代码。

  • 字符编码方案
    把数字化的字符代码编码成一系列二进制码(并能相应地反向解码)的算法。

字符(Page.396)

字符是书写的最基本的构建单元。字符可以表示字母、数字、标点、表意符号(比如在汉语中)、数学符号,或其他书写的基本单元。

字符是唯一的、抽象的语言“原子”。字形是画出每个字符时使用的特定方式。

字符编码方案(Page.399)

字符编码方案有以下3种主要类型。

  • 固定宽度
    固定宽度方式的编码用固定数量的比特表示每个编码后的字符。

  • 可变宽度(无模态)
    可变宽度方式的编码对不同的字符代码数字采用不同数量的比特。

  • 可变宽度(有模态)
    有模态的编码使用特殊的“转义”模式在不同的模态之间切换。

常见编码方案(Page.400~Page.401)

  1. 8位
  2. UTF-8
  3. iso-2022-jp
  4. euc-jp

语言标记与HTTP(Page.402~Page.407)

语言标记是命名口语的标准化字符串短语。实体的Content-Language首部字段描述实体的目标受众语言。

语言标记的类型(Page.404)。

  • 一般的语言分类(比如es代表西班牙语);
  • 特定国家的语言(比如en-GB代表英国英语);
  • 语言的方言(比如no-bok指挪威的书面语);
  • 地区性的语言(比如sgn-US-MA代表美国马撒葡萄园岛上的手语);
  • 标准化的非变种语言(比如i-navajo);
  • 非标准的语言(比如x-snowboarder-slang)。

语言标记有一个或多个部分,用连字号分隔,称为子标记(Page.404):

  • 第一个子标记称为主子标记,其值是标准化的;
  • 第二个子标记是可选的,遵循它自己的命名标准:
  • 其他尾随的子标记都是未注册的。

主子标记中只能含有字母(A~Z)。其后的子标记可以含有字母和数字,长度最多8个字符。所有标记都是不区分大小写的,也就是说,标记en和eN是等价的。但是,习惯上用全小写来表示一般的语言,而用全大写来表示特定的国家。

URI字符集合(Page.408)

URI中允许出现的US-ASCII字符的子集,可以被分成保留、未保留以及转义字符这几类。URI转义提供了一种安全的方式,可以在URI内部插入保留字符以及原本不支持的字符。

第十七章:内容协商与转码

本章主要讲解了四个问题。其中三个问题是关于内容协商技术的,还有一个是关于转码的。

内容协商技术(Page.414)

共有3种不同的方法可以决定服务器上哪个页面最适合客户端;让客户端来选择、服务器自动判定,或让中间代理来选。这3种技术分别称为客户端驱动的协商、服务器驱动的协商以及透明协商。

客户端驱动的协商(Page.415)

对于服务器来说,收到客户端请求时只是发回响应,在其中列出可用的页面,让客户端决定要看哪个,这是最容易的事情。很显然,这是服务器最容易实现的方式,而且客户端很可能选择到最佳的版本(只要列表中有让客户端选择的足够信息)。不利之处是每个页面都需要两次请求:第一次获取列表,第二次获取选择的副本。

服务器驱动的协商(Page.415)

有以下两种机制可供HTTP服务器评估发送什么响应给客户端比较合适(Page.415)。

  • 检查内容协商首部集。服务器查看客户端发送的Accept首部集,设法用相应的响应首部与之匹配。
  • 根据其他(非内容协商)首部进行变通。
透明协商(Page.419)

透明协商机制试图从服务器上去除服务器驱动协商所需的负载,并用中间代理来代表客户端以使与客户端的报文交换最小化。对内容进行缓存的时候是假设内容以后还可以重用。

转码(Page.422)

服务器可以把现存的文档转换成某种客户端可用的文档。这种选项称为转码。

格式转换(Page.422)

格式转换是指将数据从一种格式转换成另一种格式,使之可以被客户端查看。

信息综合(Page.423)

从文档中提取关键的信息片段称为信息综合(information synthesis),这是一种有用的转码操作。

嗯,这一章差不多就这些内容。

Comments