想要了解更多HTTP相关内容请重视该专栏:《HTTP彻底注解》

完好手册可重视该仓库,如有协助,麻烦给个✨

该站点也会同步更新,已满意PWA,您可安装到桌面随时/离线访问

【HTTP彻底注解】规模恳求

规模恳求

规模恳求是HTTP的一种内容协商机制,该机制答应客户端只恳求资源的部分内容。规模恳求在传送大的媒体文件,或许与文件下载的断点续传功能调配运用时非常有用。

规模恳求的工作流程

规模恳求通过在HTTP恳求标头Range中标明需求恳求的部分资源的字节规模,服务器收到恳求后将判别Range指定的规模是否超出资源的巨细。假如规模未超出资源巨细,服务器将呼应 206 Partial Content 状况码,以及Range标头指定的资源的部分内容,并带着Content-Range呼应头标明回来部分资源的字节规模/全体资源巨细;假如所恳求的规模越界,那么服务器会回来 416 Requested Range Not Satisfiable (恳求的规模无法满意)状况码,标明客户端过错。假如事先不知资源能否规模恳求,还需求事先发送一个head恳求进行检测。

【HTTP彻底注解】规模恳求

规模恳求工作流程如下:

  • 未知资源能否建议规模恳求(已知疏忽该步):对恳求资源建议一个head恳求,检测能否运用规模恳求。

  • 服务端呼应head恳求(已知疏忽该步):服务端收到head恳求后,只会回来呼应头部信息,而不回来实践的资源内容。假如回来头部信息中有包括Accept-Ranges: bytes头,则证明该资源支撑规模恳求,一起还会包括一个Content-Length头,该头标明了资源的全体巨细;假如未包括Accept-Ranges: bytes则标明不支撑规模恳求

  • 客户端建议规模恳求:客户端带着Range恳求标头,标明需求恳求的部分资源的字节规模。客户端不仅仅只能指定恳求资源的某一部分(单一规模),还能够指定恳求资源的多个部分(多重规模)

    单一规模恳求/示例

    GET /image.png HTTP/1.1
    Range: bytes=0-1023
    

    多重规模恳求示例

    GET /image.png HTTP/1.1
    Range: bytes=0-1023, 2000-6576
    
  • 服务端呼应规模恳求:服务端收到规模恳求后,将判别恳求资源是否存在Range中指定的字节规模,假如存在,服务端将正确处理恳求,并只回来该规模内的数据,带着Content-Range呼应头标明回来部分资源的字节规模/全体资源巨细,带着Content-Length呼应头标明呼应的呼应体的巨细,运用206 Partial Content 状况码来指示成功呼应恳求的部分内容。假如所恳求的规模越界,那么服务器会回来 416 Requested Range Not Satisfiable (恳求的规模无法满意)状况码,标明客户端过错。

    单一规模恳求呼应示例

    HTTP/1.1 206 Partial Content
    Content-Range: bytes 0-1023/146515
    Content-Length: 1024
    ...
    (binary content)
    

    多重规模恳求呼应示例

    HTTP/1.1 206 Partial Content
    Content-Type: multipart/byteranges; boundary=3d6b6a416f9b5
    Content-Length: 2082
    --3d6b6a416f9b5
    Content-Type: image/png
    Content-Range: bytes 0-1000/146515
    (binary content)
    --3d6b6a416f9b5
    Content-Type: image/png
    Content-Range: bytes 2000-3000/146515
    (binary content)
    --3d6b6a416f9b5
    

【HTTP彻底注解】规模恳求

与规模恳求相关的三种呼应状况:

  • 在恳求成功的情况下,服务器会回来 206 Partial Content 状况码。

  • 在恳求的规模越界的情况下(规模值超过了资源的巨细),服务器会回来 416 Requested Range Not Satisfiable (恳求的规模无法满意)状况码。

  • 在不支撑规模恳求的情况下,服务器会回来 200 OK 状况码。

保证资源完好性

规模恳求每次都只恳求资源的部分内容,那么怎么保证两次恳求的资源未产生过更改呢?怎么保证资源的完好性呢?比如我运用规模恳求恳求了资源的一半内容,过了两天之后,我又持续运用规模恳求恳求资源的另一半内容,此刻我是无法承认我恳求的另一半资源未产生过更改,且无法保证两份资源能够拼合在一起还原为一份完好资源。

【HTTP彻底注解】规模恳求

为处理该问题,HTTP协议规则了一个特定的恳求头 If-Range——来避免这种情况的产生。运用If-Range恳求头与Etag呼应头调配运用,即可对恳求资源进行版别验证;运用If-Range恳求头与Last-Modified呼应头调配运用,即可对恳求资源进行时刻验证。

根据时刻的验证——Last-Modified/If-Range

【HTTP彻底注解】规模恳求

当客户端首次建议规模恳求恳求资源部分内容时,服务器的呼应会带着Last-Modified呼应标头来标明恳求资源最终被修正的时刻,一般情况下,服务器会根据文件体系中资源的最终修正时刻主动设置这个标头。 如下所示:

HTTP/1.1 206 Partial Content
Content-Range: bytes 0-1023/146515
Content-Length: 1024
Last-Modified: Tue, 22 Feb 2022 22:00:00 GMT
........

客户端收到呼应后需求自即将这个时刻存储起来,后续客户端再次对该资源进行规模恳求时,需求自行带着一个If-Range恳求头,并将保存的时刻值放入其间,以告知浏览器,上一次规模恳求恳求的资源最终被修正的时刻,如下所示:

GET /image.png HTTP/1.1
Range: bytes=1024-2047
If-Range: Tue, 22 Feb 2022 22:00:00 GMT
......

服务器收到该恳求后会比较恳求中的 If-Range 值与当时资源的最终修正时刻,假如内容自指定时刻以来没有更改,则证明资源未产生更改,此刻浏览器会回来状况码为206 Partial 的呼应,以及相应的部分资源;假如恳求资源产生了更改,那么就会回来状况码为 200 OK 的呼应,一起回来整个资源。

If-Range值与当时资源的最终修正时刻相同的呼应

HTTP/1.1 206 Partial Content
Content-Range: bytes 1024-2047/146515
Content-Length: 1024
Last-Modified: Tue, 22 Feb 2022 22:00:00 GMT
........

If-Range值与当时资源的最终修正时刻不同的呼应

HTTP/1.1 200 ok
Last-Modified: Tue, 23 Feb 2022 22:00:00 GMT
Content-Length: 146515
.................

根据时刻的验证虽然避免了从头传输相同的资源的问题,但它也存在许多问题:

  • 时刻精度问题: 时刻戳一般只有秒等级的精度,这可能导致在某些情况下无法检测到资源的真正修正。假如两次修正之间的时刻距离很短,可能无法捕捉到变化。
  • 服务器时钟回退: 假如服务器的时钟回退(例如,因为时钟同步服务的干涉),可能会导致客户端以为资源已通过期,尽管实践上它仍然是最新的。
  • 资源未被修正但最终修正时刻已变: 有时资源的内容并没有实践修正,但因为某些原因,最终修正时刻被更新了。这可能导致不必要的资源传输。

为了处理这些问题,HTTP缓存推出了根据版别的验证作为替代方案。

根据版别的验证——ETag/If-Range

【HTTP彻底注解】规模恳求

当客户端首次建议规模恳求恳求资源部分内容时,服务器的呼应会带着ETag呼应标头来标明恳求资源的版别,该标头的值是服务器生成的恣意值,因而服务器能够根据他们挑选的任何方法自在设置值——例如主体内容的哈希或版别号,如下所示:

HTTP/1.1 206 Partial Content
Content-Range: bytes 0-1023/146515
Content-Length: 1024
ETag: "deadbeef"
........

客户端收到呼应后需求自即将ETag的值存储起来,后续客户端再次对该资源进行规模恳求时,需求自行带着一个If-Range恳求头,并将保存的ETag值放入其间,以告知浏览器,上一次规模恳求恳求的资源的版别,如下所示:

GET /image.png HTTP/1.1
Range: bytes=1024-2047
If-Range: "deadbeef"
......

服务器收到该恳求后会比较恳求中的 If-Range 值与当时资源版别号是否相同,假如当时资源版别号与恳求中的If-Range 值相同,则证明资源未产生更改,此刻浏览器会回来状况码为206 Partial 的呼应,以及相应的部分资源;假如当时资源版别号与恳求中的If-Range 值不同,那么就会回来状况码为 200 OK 的呼应,一起回来整个资源。

If-Range值与当时资源版别相同的呼应

HTTP/1.1 206 Partial Content
Content-Range: bytes 1024-2047/146515
Content-Length: 1024
ETag: "deadbeef"
........

If-Range值与当时资源版别不同的呼应

HTTP/1.1 200 ok
ETag: "sdaeadbeef"
Content-Length: 146515
.................

相关标头

Accept-Ranges 呼应标头

呼应标头Accept-Ranges标明恳求资源是否支撑规模恳求。当浏览器发现Accept-Ranges头时,能够尝试持续中断了的下载,而不是从头开始。

参数

该呼应标头并无其他参数

取值

  • none

    标明不支撑任何规模恳求,因为其同等于没有回来此头部,因而很少运用。

  • bytes

    标明支撑规模恳求,其规模单位为bytes(字节)

示例

Accept-Ranges: bytes

Content-Length 实体标头

实体标头Content-Length标明音讯主体的巨细,用来指明发送给接收方的音讯主体的巨细,单位为bytes(字节)

参数

该实体标头并无其他参数

取值

  • <length>

    十进制数字,标明音讯体的长度,单位为bytes(字节)。

示例

Content-Length:1024

Range 恳求标头

恳求标头Range指定了一系列的字节规模,用于告知服务器客户端需求恳求资源哪些部分的内容。假如规模未超出资源巨细,服务器将呼应 206 Partial Content 状况码,以及Range 头字段恳求的相应部分,假如所恳求的规模不合法,那么服务器会回来 416 Range Not Satisfiable 状况码,标明客户端过错。

参数

该恳求标头并无其他参数

取值

  • <unit>=[<star-end>,<start->……]

    <unit>: 规模所选用的单位,一般是字节(bytes)。

    start: 一个整数,标明规模的起始值。

    end: 一个整数,标明规模的完毕值,假如不存在,标明此规模一向延伸到文档完毕。

示例

Range: bytes=200-1000, 2000-6576, 19000-

Content-Range 呼应标头

呼应标头Content-Range标明呼应的部分资源的字节规模,以及资源的全体巨细。

参数

该呼应标头并无其他参数

取值

  • <unit> <star-end>/<size>

    <unit>: 规模所选用的单位,一般是字节(bytes)。

    start: 一个整数,标明规模的起始值。

    end: 一个整数,标明规模的完毕值。

    size: 资源的全体巨细。

示例

Content-Range: bytes 200-1000/67589

If-Range 恳求标头

恳求标头If-Range当与Last-Modified呼应标头调配时,需求指定一个肯定时刻,通过查看资源的最终修正时刻是否更改,来查看资源是否产生变化;当与Etag呼应标头调配时,需求指定一个版别号,通过查看资源是否与给定版别号匹配,来查看资源是否产生更改

当资源未产生更改服务器才会回复206 Partial Content状况码,以及Range 头字段恳求的相应部分;假如资源产生更改,服务器将会回来 200 OK 状况码,并回来完好的恳求资源。

参数

该恳求标头并无其他参数。

取值

  • <date>

    指定一个肯定时刻,标明期望服务器查看资源的最终修正时刻是否更改,也便是查看资源是否产生变化。

  • “<etag_value>”

    指定一个版别号,标明期望服务器查看资源是否与给定版别号匹配,也便是查看资源是否产生变化。

示例

If-Range: Wed, 21 Oct 2015 07:28:00 GMT
If-Range: "deadbeef"

Last-Modified 呼应标头

呼应标头Last-Modified指定了呼应的资源最终被修正的时刻,一般情况下,服务器会根据文件体系中资源的最终修正时刻主动设置这个标头。

参数

该呼应标头并无其他参数。

取值

  • <date>

    一个肯定时刻,指定呼应的资源最终被修正的时刻。

示例

Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT

ETag 呼应标头

呼应标头ETag指定了一个版别号,标明呼应的资源的版别,该标头的值是服务器生成的恣意值,因而服务器能够根据他们挑选的任何方法自在设置值——例如主体内容的哈希或版别号。

参数

  • W/ 可选

    'W/'(巨细写灵敏) 标明运用弱验证器。弱验证器很容易生成,但不利于比较。强验证器是比较的理想挑选,但很难有效地生成。相同资源的两个弱Etag值可能语义同等,但不是每个字节都相同。

  • “<etag_value>”

    指定一个版别号,没有明确指定生成 ETag 值的方法。一般,运用内容的散列,最终修正时刻戳的哈希值,或简略地运用版别号。例如,MDN 运用 wiki 内容的十六进制数字的哈希值。

示例

ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
ETag: W/"0815"

本节参阅

转载需求通过本人同意,并标明出处!