Web 框架下网络通信的基础,http 通信报文,请求响应头字段说明,http 缓存机制,http 协议的缺点……
计算机与网络设备之间,不同的硬件、操作系统之间要实现通信,需要事先约定规则,比如,由谁发起通信、使用什么语言通信、怎样结束通信,乃至于电缆的规格等,这些规则统称为协议(protocol)。
与互联网相关的协议集合总称为TCP/IP 协议族,从这个意义上讲,HTTP 协议 是 TCP/IP 协议的一个子集,本章只介绍 HTTP 协议 及与其有关的 TCP/IP 协议内容。
一 Web 通信基础
HTTP 协议, 也叫超文本传输协议,是一种文档传递的协议,Web 浏览器在地址栏输入 URL 从服务端获取文件资源等信息,就是建立在该协议上的。
WWW(万维网),其理念是借助多文档之间相互关联形成的超文本。WWW 的建构技术包含三种:页面的文本标记语言 HTML(标准通用标记语言 SGML);文档传递协议 HTTP;指定文档所在位置的 URL。
TCP/IP(传输控制协议/网际协议),是指能够在多个不同网络间实现信息传输的协议族,其按层次分分为:应用层、传输层、网络层和数据链路层。
URI,由某个协议方案(http、ftp...)表示的资源的定位标识符,用字符串标识的某一互联网资源;URL,标识资源的地点。由此可见 URL 是 URI 的子集。
其中登录信息是可选的。
二 HTTP 协议基础
HTTP 协议,通过客户端的请求和服务端的响应达成通信。
1. 通信报文
请求报文由请求方法、请求URI、协议版本、可选的请求首部字段和内容实体构成的。
响应报文由协议版本、状态码、用以解释状态码的短语、可选的响应首部字段和实体主体构成。
2. HTTP 请求特性
3. HTTP 请求方法
| 方法 | 说明 |
|---|---|
| GET | 获取资源 |
| POST | 传输实体主体,主要目的不是获取响应的主体内容 |
| PUT | 传输文件 |
| HEAD | 获取报文首部 |
| DELETE | 删除文件 |
| OPTIONS | 询问支持的方法 |
| TRACE | 追踪路径 |
| CONNECT | 要求用隧道协议连接代理 |
三 HTTP 报文信息及状态码
1. HTTP 报文构成
HTTP 在传输数据时,可以把数据原样传输,也可以在传输过程中对数据编码、压缩数据以提升传输速度;在传输大容量数据时,也可以把数据分割成多块传输编码。
如果传输的数据包含多种不同类型的数据,比如文本、图片、视频等,HTTP 协议使用了多部分对象集合(Multipart)的机制处理这种情况,需要在报文首部添加 Content-Type 属性。
多部分对象集合的类型:
- multipart/form-data: 在 web 表单文件上传时使用
- multipart/byteranges: 状态码206响应报文包含了多个范围的内容时使用
范围请求,指定范围发送的请求,比如下载过程中网络中断,等网络再连上时,不用从头下载,通过范围请求从中断处继续下载。需要设置首部字段,如:Range: bytes=5001-10000。
2. HTTP 报文首部
首部字段构成:
首部字段名: 字段值
示例:
Content-Type: text/html
可以是多个值:
Keep-Alive: timeout=15, max=100
报文首部中如果出现重复的首部字段名,这种情况目前没有规范约束,不同浏览器有不同的处理。
首部字段的四种类型:
- 通用首部字段
- 请求首部字段
- 响应首部字段
- 实体首部字段
通用首部字段
| 字段名 | 说明 |
|---|---|
| Cache-Control | 控制缓存的行为 |
| Connection | 逐跳首部、连接的管理 |
| Date | 创建报文的日期时间 |
| Pragma | 报文指令 |
| Trailer | 报文末端的首部一览 |
| Transfer-Encoding | 指定报文主体的传输编码方式 |
| Upgrade | 升级为其他协议 |
| Via | 代理服务器的相关信息 |
| Warning | 错误通知 |
请求首部字段
| 字段名 | 说明 |
|---|---|
| Accept | 用户代理可处理的媒体类型 |
| Accept-CharSet | 优先的字符集 |
| Accept-Encoding | 优先的内容编码 |
| Accept-Language | 优先的语言 |
| Authorization | Web 认证信息 |
| Expect | 期待服务器的特定行为 |
| From | 用户的电子邮箱地址 |
| Host | 请求资源所在服务器 |
| If-Match | 比较实体标记(ETag) |
| If-Modified-Since | 比较资源的更新时间 |
| If-None-Match | 比较实体标记(与 If-Match 想反) |
| If-Range | 资源未更新时发送实体Byte的范围请求 |
| If-Unmodified-Since | 比较资源的更新时间(与 If-Modified-Since 想反) |
| Max-Forwards | 最大传输逐跳数 |
| Proxy-Authorization | 代理服务器要求客户端的认证信息 |
| Range | 实体的字节范围请求 |
| Referer | 对请求中URI的原始获取方 |
| TE | 传输编码的优先级 |
| User-Agent | HTTP客户端程序的信息 |
响应首部字段
| 字段名 | 说明 |
|---|---|
| Accept-Ranges | 是否接收字节范围请求 |
| Age | 推算资源创建经过时间 |
| ETag | 资源的匹配信息 |
| Location | 令客户端重定向至指定URI |
| Proxy-Authenticate | 代理服务器对客户端的认证信息 |
| Retry-After | 对再次发起请求的时机要求 |
| Server | HTTP 服务器的安装信息 |
| Vary | 代理服务器缓存的管理信息 |
| WWW-Authenticate | 服务器对客户端的认证信息 |
实体首部字段
| 字段名 | 说明 |
|---|---|
| Allow | 资源可支持的 HTTP 方法 |
| Content-Encoding | 实体主体适用的编码方式 |
| Content-Language | 实体主体的自然语言 |
| Content-Length | 实体主体的大小(单位:字节) |
| Content-Location | 替代对应资源的URI |
| Content-MD5 | 实体主体的报文摘要 |
| Content-Range | 实体主体的位置范围 |
| Content-Type | 实体主体的媒体类型 |
| Expires | 实体主体的过期日期时间 |
| Last-Modified | 资源的最后修改日期时间 |
3. 状态码
| 状态码 | 类别 | 原因短语 |
|---|---|---|
| 1XX | Informational(信息性状态码) | 接收的请求正在处理 |
| 2XX | Success(成功状态码) | 请求正常,处理完毕。200-OK,204-无资源返回;206-范围请求。 |
| 3XX | Redirection(重定向状态码) | 需要进行附加操作以完成请求。301-永久重定向;302-临时重定向;303-302+GET方式请求;304-服务端资源没变,使用客户端缓存。 |
| 4XX | Client Error(客户端错误状态码) | 服务器无法处理请求。400-请求报文存在错误;401-须有认证信息;403-没有权限访问;404-无法找到资源。 |
| 5XX | Server Error(服务器错误状态码) | 服务器处理请求出错。500-服务端执行请求发生错误;503-服务端超负荷或正停机维护。 |
四 与 HTTP 协作的 Web 服务器
一台服务器可以搭建多个独立域名的 Web 网站,也就是说多个不同域名的网址可能指向同一个 ip 地址。
除了客户端和服务端,HTTP 通信时,还有一些用于通信数据转发的程序,比如代理、网关、隧道等。
1. 代理
代理,是一种有转发功能的应用程序,它扮演了位于服务器和客户端“中间人”的角色。
使用代理服务器的理由有:利用缓存技术减少网络带宽的流量,组织内部针对特定网站的访问控制等等。
- 缓存代理:预先将资源的副本保存在代理服务器上,这样不用再访问源服务器,可以直接使用代理服务器上的资源作为响应。
- 透明代理:转发请求或响应时,不对报文做任何加工。反之,称为“非透明代理”。
缓存
缓存,是指代理服务器或客户端本地磁盘上保存的资源副本。利用缓存可以减少对源服务器的访问,节省通信流量和通信时间。
2. 网关
网关,是转发其他服务器通信数据的服务器,接收从客户端发送来的数据请求时,它就像拥有资源的源服务器一样对请求进行处理。网关能使通信线路上的服务器提供非 HTTP 协议服务。
3. 隧道
在相隔很远的客户端和服务器之间进行中转,并保持双方通信连接的应用程序。
五 HTTP 缓存机制
1. 缓存位置
根据优先级的缓存位置如下:
- Service Worker: 服务器与浏览器之前的“中间人”,如果在网站中注册了Service Worker,那么它可以拦截该网站所有的请求。
- Memory Cache:内存中的缓存。缓存持续性很短,关闭标签页,内存中的缓存就被释放了。
- Disk Cache:硬盘中的缓存。
- Push Cache:Push Cache 是 HTTP/2 中的内容,当以上三种缓存都没有命中时,它才会被使用。缓存时间很短暂,只在会话(Session)中存在,一旦会话结束就被释放。
2. 缓存策略
最好的方式是,强缓存与协商缓存配合使用,争取最大化的减少请求,利用缓存,节约流量。
浏览器缓存过程:
再次请求时,判断是否在缓存时间内,若在直接用缓存;如果不在则访问服务器,服务器收到请求后发现请求首部字段有 If-None-Match, 则与被请求资源的唯一标识进行比对。 不同,说明资源又被改动过,则响应整片资源内容,返回状态码200; 相同,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用所保存的cache。
再次请求服务器时,服务器收到请求后发现请求首部字段有 If-Modified-Since, 则与被请求资源的最后修改时间进行比对。 若资源的最后修改时间大于 If-Modified-Since,说明资源又被改动过,则响应整片资源内容,返回状态码200; 若资源的最后修改时间小于或等于If-Modified-Since,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用所保存的 cache。
3. 用户行为
-
F5 刷新:浏览器会设置max-age=0,跳过强缓存判断,进行协商缓存判断。
-
Ctrl + F5 强制刷新:跳过强缓存和协商缓存,直接从服务器拉取资源。
4. 不缓存
禁止缓存:
Cache-Control: no-cache, no-store, must-revalidate
或者 Expires 设为当前时间之前。
<script type=“text/javascript” src=“/js/test.js?+Math.random()”></script>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache, must-revalidate">
<meta http-equiv="expires" content="Wed, 26 Feb 1997 00:00:00 GMT">
5. 代码实现
前端的实现可在<meta> <script>标签中设置,也可在请求实例中添加请求头,如再 ajax 请求中设置 header属性,在 XMLHttpRequest 中设置 xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded")等。
响应的缓存信息要在后台设置。
六 HTTP 缺点
HTTP 的缺点:
- 通信使用明文,内容可能被窃听。
- 不验证通信方的信息,有可能遭遇伪装。
- 无法证明报文的完整性,有可能已遭篡改。
- 通信必须由客户端发起请求。
HTTP 协议中没有加密机制,可以通过和 SSL(安全套接层)或 TLS(安全传输层协议)的组合使用,加密通信内容。
HTTP 和 SSL 的组合,被称为HTTPS(超文本传输安全协议)。
HTTPS = HTTP + 加密 + 认证 + 完整性保护
HTTPS 的通信速度相比 HTTP 会变慢。
参考:《图解HTTP》 、 alex夏夜