接上篇,本篇将讲一些更加深刻理论的内容。ajax
为了让只认识二进制的计算机显示各类各样的文字咱们发明了编码规范,好比常见的GBK、ASCⅡ、Unicode等。编码规范由三部分组成:字库表、字符集、编码方式。数据库
显示文字的原理就是:一串二进制数据,经过一种“编码方式”,分割、转化成“字符集”中的地址,而后在“字库表”中找到对应的字符图形数据,输出设备依据图形数据显示出字。
通常编码与解码须要相同的编码规范才能保证正确,虽然也有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字符集的字符”和“保留字”还应该分开说明:安全
http://g.cn/search?a=b
这里的等于号是结构的一部分因此不须要编码;http://g.cn/search?a=b%3D
这里本来是a=b=,这里的等于号是参数值,非结构的一部分,因此被编码成“%3D”。常见的认证方式可分为4种:BASIC认证(基本认证)、DIGEST认证(摘要认证)、SSL客户端认证、FormBase认证(基于表单认证)。
前两种是HTTP协议的标准认证方式,但其实如今已经不多使用;后两种是由客户端自行实现,通常SSL客户端认证用于网银等高安全环境,FormBase认证是如今最经常使用的认证方式。服务器
示意图以下:(来自MDN)cookie
为了弥补BASIC认证存在的弱点,从HTTP/1.1起就有了DIGEST认证。
DIGEST认证一样使用质询/响应的方式,但不会像BASIC认证那样直接发送明文密码。过程相似于BASIC认证,示意图参考上面的。网络
借由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版本以前的一个特色是“无链接”,这个也就是短链接,只是在后续版本种变成了可选项。
每次请求都通过”这样的过程如图:
HTTP/1.1起,默认使用长链接。也就是说,就是只创建一次TCP链接,屡次资源请求都复用该TCP链接,完成后再关闭。
每次请求都通过这样的过程如图:
长链接虽然增长了TCP链接的复用率,但实质上仍是基于请求/响应模式的,并不能实现及时更新、或是服务器主动向客户端发送信息。因而就有了“ajax轮询”、“ajax长轮询(Long Poll)”这两种变通手段。
这两种变通手段都是以消耗大量服务器资源为代价,所以为了根本解决这个问题,后来发展出了WebSocket协议,这就是后话了。
代理扮演的是“中间人”角色,对于链接到它的客户端来讲,它是服务端;对于要链接的服务端来讲,它是客户端。它就负责在两端之间来回传送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 |
经过在报文头里两个参数实现的,客户端发请求时对应的是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\](文件总大小)
断点续传是被动的增量下载,多线程是主动的分片下载,但使用都是Range模式。