「开位」你所应该知道的HTTP——进阶篇

前言

接上篇,本篇将讲一些更加深刻理论的内容。ajax

URL的编码

编码规范

为了让只认识二进制的计算机显示各类各样的文字咱们发明了编码规范,好比常见的GBK、ASCⅡ、Unicode等。编码规范由三部分组成:字库表、字符集、编码方式。数据库

  • 字库表:存储字符图形的集合(数据库)。
  • 字符集:字库表每一个字符对应的地址(通常是数字)。
  • 编码方式:在内存中表示字符集地址的方式,不一样编码方式适用的场景不一样,使用的内存空间不同。(如Unicode有utf-八、utf-16等编码方式)

显示文字的原理就是:一串二进制数据,经过一种“编码方式”,分割、转化成“字符集”中的地址,而后在“字库表”中找到对应的字符图形数据,输出设备依据图形数据显示出字。
通常编码与解码须要相同的编码规范才能保证正确,虽然也有Unicode兼容ASCⅡ的状况,但反过来ASCⅡ就没法编码和解码Unicode。segmentfault

“%编码”规范

背景

HTTP协议规范里URL是采用ASCⅡ编码规范,理论上对于采用Unicode编码的中文等其余文字是不支持的,因此若是URL中含有非ASCII字符集的字符(以及保留字,好比&),要对其进行编码,因而有了“%编码”规范。浏览器

RFC3986文档规定,Url中只容许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及全部保留字符。

定义

对于URL中属于ASCⅡ字符集的非保留字不作编码;对URL中的保留字须要取其ASCⅡ内码,而后加上“%”前缀进行编码;对于URL中非ASCⅡ字符须要取其Unicode内码,而后加上“%”前缀进行编码。缓存

额外补充

这里对于“非ASCII字符集的字符”和“保留字”还应该分开说明:安全

  • “非ASCII字符集的字符”是必定会被编码的。
  • “保留字”是在产生歧义的状况下才须要编码。好比:http://g.cn/search?a=b这里的等于号是结构的一部分因此不须要编码;http://g.cn/search?a=b%3D这里本来是a=b=,这里的等于号是参数值,非结构的一部分,因此被编码成“%3D”。

认证方式

常见的认证方式可分为4种:BASIC认证(基本认证)、DIGEST认证(摘要认证)、SSL客户端认证、FormBase认证(基于表单认证)。
前两种是HTTP协议的标准认证方式,但其实如今已经不多使用;后两种是由客户端自行实现,通常SSL客户端认证用于网银等高安全环境,FormBase认证是如今最经常使用的认证方式。服务器

BASIC认证

  1. 客户端发送请求;
  2. 服务器返回401,头部信息:WWW-Authenticate:Basic realm="xxx",告知须要验证;
  3. 客户端将用户名和密码以Base64方式编码后发送,头部信息:Authorization:Basic <base64串>;
  4. 服务器验证经过返回200,不然重复②。

示意图以下:(来自MDN)
HTTPAuth.pngcookie

DIGEST认证

为了弥补BASIC认证存在的弱点,从HTTP/1.1起就有了DIGEST认证。
DIGEST认证一样使用质询/响应的方式,但不会像BASIC认证那样直接发送明文密码。过程相似于BASIC认证,示意图参考上面的。网络

  1. 客户端发送请求;
  2. 服务器返回401,头部信息:WWW-Authenticate:Digest realm="xxx",nonce="<质询码>" algorithm=<加密方式>,qop="<保护质量参数>",告知须要验证;
  3. 客户端回传②中的全部信息,并加上username、url、response字段,response就是通过用户名密码等信息加密而已的字符串;
  4. 服务器使用相同的加密方法获得一个字符串,将它与response比较,相同就经过返回200,不然重复②。

SSL客户端认证

借由HTTPS的客户端证书完成认证的方式。凭借客户端证书认证,服务器可确认访问是否来自已登陆的客户端。session

基于表单的认证

基于表单的认证方式并非在HTTP协议中定义,是由Web应用程序各自实现。好比session-cookie机制。

链接管理模型

在HTTP/1.x里有多种模型:短链接,长链接,和HTTP流水线。
HTTP流水线并无浏览器支持,已经被HTTP/2.0的多路复用特性所取代,这里就不详细讨论了。

链接的长与短只是相对的概念,并无严格意义上规定多久才算长。
讨论HTTP的长链接与短链接,本质是讨论TCP链接的复用状况。
由请求报文头和响应报文头里的Connection字段决定,值为close则为短链接,值为keep-alive则为长链接,只有服务器与客户端协商一直才会进行长链接,而且双方在任意时刻均可以关闭,彼此都不受影响。

短链接

HTTP/1.0中,默认使用的是短链接。也就是说,浏览器和服务器每进行一次HTTP操做,就创建一次TCP链接,结束就中断。
基础篇(传送门)中讲到HTTP协议在1.0版本以前的一个特色是“无链接”,这个也就是短链接,只是在后续版本种变成了可选项。
每次请求都通过”这样的过程如图:

短链接

长链接(keep-alive链接)

HTTP/1.1起,默认使用长链接。也就是说,就是只创建一次TCP链接,屡次资源请求都复用该TCP链接,完成后再关闭。
每次请求都通过这样的过程如图:

长链接

缺陷及变通手段

长链接虽然增长了TCP链接的复用率,但实质上仍是基于请求/响应模式的,并不能实现及时更新、或是服务器主动向客户端发送信息。因而就有了“ajax轮询”、“ajax长轮询(Long Poll)”这两种变通手段。

  • ajax轮询:原理很简单,就是每隔一段时间就发起一次请求,已到达及时更新的目的。
  • ajax长轮询:服务器接收到请求后若是没有更新内容就不响应,客户端也不作超时处理一直处于等待状态,一直等到有更新内容,服务器才响应,客户端接收到响应后又再发起请求,如此往复。

这两种变通手段都是以消耗大量服务器资源为代价,所以为了根本解决这个问题,后来发展出了WebSocket协议,这就是后话了。

Web代理

定义

代理扮演的是“中间人”角色,对于链接到它的客户端来讲,它是服务端;对于要链接的服务端来讲,它是客户端。它就负责在两端之间来回传送HTTP报文。

示意图以下:

Web代理

应用

  • 抓包调试:好比经常使用的抓包软件Fiddler和Charles。
  • 匿名访问:常见的在线代理网站。
  • 过滤器:一些绿色净网的软件。

Web网关

定义

网关扮演的是“协议转换器”角色,能够做为某种翻译器使用,它抽象出了一种可以到达资源的方法。网关是资源和应用程序之间的粘合剂。
代理与网关的区别:代理是转发相同协议的数据,网关是转换不一样协议的数据。

示意图以下:

Web网关

应用

  • (HTTP/*) 服务器端Web网关
  • (HTTP/HTTPS) 服务器端安全网关
  • (HTTPS/HTTP) 客户端安全加速器网关
  • 资源网关

内容协商机制

概述

指客户端和服务器就响应的资源内容进行交涉,而后提供给客户端最为合适的资源。内容协商会以响应资源的语言,字符集,编码方式等做为判断的基准。

协商方式及优缺点

  • 客户端驱动:客户端发起请求,服务器发送可选项列表,客户端做出选择后再发送第二次请求。
    优势:容易实现,给用户选择权。
    缺点:增长访问次数和延迟。
  • 服务器驱动:服务器检查客户端的请求头部集并决定提供哪一个版本的页面。(如今最广泛)
    优势:比较快,没有额外开销,支持优先级匹配。
    缺点:头部集都不匹配的时候,服务器只能猜想。
  • 透明协商:某个中间设备(一般是缓存代理)表明客户端进行协商。
    优势:比较快。
    缺点:须要中间设备,非http标准。

服务器驱动内容协商原理

客户端经过请求报文头传递告诉服务器支持状况,而且能够带有近似匹配的优先级,服务器回应的响应报文头里进行确认,就完成了内容协商。

  • 相关请求报文头
字段名 说明文字
Accept 告诉服务器本身能接受的媒体类型
Accept-Language 能接受的语言
Accept-Charset 能接受的字符集(如unicode)
Accept-Encoding 能接受的编码方式(如utf-8)
  • 相关响应报文头
字段名 说明文字
Content-Type 对应Accept
Content-Language 对应Accept-Language
Content-Type 对应Accept-Charset
Content-Encoding 对应Accept-Encoding
  • 近似匹配(优先级)
    好比:Accept-Encoding:en;q=0.5,fr;q=0.0,nl;q=1.0,tr;q=0.0
    这里nl的优先级是1.0,最高优先级,因此会优先返回。

断点续传和多线程

概述

经过在报文头里两个参数实现的,客户端发请求时对应的是Range,服务器响应时对应的是Content-Range 。

请求报文头

Range用于请求头中,指定第一个字节的位置和最后一个字节的位置。
格式为:

Range:(unit=first byte pos) - \[last byte pos\]

响应头

HTTP/1.1 200 Ok(不使用断点续传方式)
HTTP/1.1 206 Partial Content(使用断点续传方式)
Content-Range用于响应头中,在发出带Range的请求后,服务器会在Content-Range头部返回当前接受的范围和文件总大小。
格式为:

Content-Range:bytes(unit first byte pos) - \[last byte pos\]/\[entity length\](文件总大小)

例子

  1. 客户端下载一个1024K的文件 已经下载了其中512K;
  2. 网络中断,客户端请求续传 所以须要在HTTP头申明本次须要续传的片断“Range:bytes=512000- ”这个头通知服务端从文件的512K位置开始传输文件;
  3. 服务端收到断点续传请求,从文件的512K位置开始传输,而且在HTTP头中增长“Content-Range:bytes 512000- /1024000”而且此时服务返回的HTTP状态码应该206,而不是200。

关于多线程

断点续传是被动的增量下载,多线程是主动的分片下载,但使用都是Range模式。

相关文章
相关标签/搜索