《图解HTTP》学习总结

前言

本文记录了学习《图解 HTTP》的过程和思考,以及一些学习笔记的分享。个人认为这本书可以作为 HTTP 的入门,通读一遍对 HTTP 有个直观的了解即可,具体的实现细节应该去查阅其他更详细的书,本书可能并不能担任工具书的角色。

第一章 基础概念

  • 什么是 HTTP:HTTP 实际上就是规定客户端和服务端如何进行「交流」,这也是「协议」干的事。即我向你发出了信息,你如何理解这段信息,同时你回复了我信息,我又该如何理解。
  • 相关协议栈:HTTP 涉及 TCP/IP 协议,本书中不需要了解细节,只要大致知道它们是干什么的就行。
    • IP 协议:根据 IP 地址和 MAC 地址(对方的地址),将各种数据包传送给对方
    • ARP 协议:通信必须要有对方的 MAC 地址,该协议通过 IP 地址查询 MAC 地址
    • TCP 协议:确保通信的可靠性,即信息一定确认送达对方
  • URI:统一资源标识符,标识某一个资源,精确到某个位置的某个资源
  • URL:统一资源定位符,标识某一个资源地点,即互联网上的某个位置(URI 包含 URL)

第二章 简单的 HTTP 协议

HTTP 请求报文基本格式:

|请求方式|请求资源对象|协议版本|
|请求首部字段|
...
|内容|
...

GET /index.html HTTP/1.1
Host: hackr.jp
...

...

HTTP 响应报文基本格式:

|协议版本|状态码|
|响应首部字段|
...
|资源主体|
...

HTTP/1.1 200 OK
Data: Tue, 10 Jul 2012 ...
Content-Length: 362
...
<html>...
...

请求 URI 的两种方式:

1. 完整请求URI
GET http://hackr.jp/index.html HTTP/1.1

2. 在首部字段Host中写明
GET /index.html HTTP/1.1
Host: hackr.jp

HTTP 请求方式:

  • GET:从服务器获取资源,请求 URI 所标识的资源
  • POST:向服务器传输资源,获得服务器返回的处理结果
  • HEAD:和 GET 一样,只不过只获得报文首部,不获得主体(通常用于确认 URI 的有效性和资源更新的日期时间等相关信息)
  • OPTIONS:请求 URI 指定的资源所支持的方法,返回可用的方法(如 GET、POST)
  • CONNECT:通信过程建立隧道,使用隧道协议(SSL、TLS)进行 TCP 通信

持久连接:由于 HTTP 连接采用 TCP,每个资源都需要进行 TCP 连接和断开,开销大,引入持久连接——只要没有明确提出断开,则保持 TCP 连接状态
注:HTTP/1.1 中所有的连接默认都是持久连接

管线化:一个请求无需等到响应即可继续发送下一个请求

Cookie:HTTP 不会保存状态,无持久化处理,只专注于当前,为了保存某些用户状态,引入 Cookie。根据服务器端发送的响应报文内的 Set-Cookie,决定是否保存 Cookie。当有 Cookie之后,客户端在下次发送请求时,会将 Cookie 加入请求中,这些用户状态信息就保存在 Cookie 中

cookie示例:

初次请求报文:没有 Cookie
GET /reader/ HTTP/1.1
Host: hackr.jp

服务器响应报文:生成 Cookie 信息
HTTP/1.1 200 OK
Date: ...
Server: Apache
<Set-Cookie: sid=123456; ...>
...

再次请求报文:顺带发送 Cookie
GET /image/ HTTP/1.1
Host: hackr.jp
Cookie: sid=123456

第三章 HTTP 报文

HTTP 报文结构:

  • 报文首部:请求或响应的内容及属性
  • 空行:间隔作用,区分首部和主体
  • 报文主体:资源

报文首部:

  • 请求报文首部:
    • 请求行:请求方式、URI、协议版本
    • 请求首部字段、 通用首部字段、实体首部字段、其他字段
  • 响应报文首部:
    • 状态行:协议版本、响应结果、原因短语
    • 响应首部字段、通用首部字段、实体首部字段、其他字段

压缩传输编码:对报文主体进行压缩传输

  • gzip:GNU zip
  • compress:UNIX 系统的标准压缩
  • deflate:zlib
  • identity:不编码

分块传输编码:在 HTTP 通信中,如果实体资源过多,可以将数据分割成多块,这样可以让浏览器逐步显示,而不是一直不显示直到接收完毕再一起全部显示

在一个报文主体中传输多个对象:boundary 标识分隔符是什么,在某个部分中仍然可以继续嵌套多对象

Content-Type: multipart/form-data; boundary=AaB03x

--AaB03x
//对象1
Content-Disposition: form-data; name=".."
...
--AaB03x
//对象2
Content-Disposition: form-data; name=".."
...
--AaB03x-- //标识结束

断点续传:某个大容量资源,中断过后从中断点继续传输,通过范围请求 Range 来确定

请求报文:
GET ...
Host: ...
Range: bytes=5001-10000 //字节范围从5001-10000
...

响应报文:
...
Content-Range: bytes 5001-10000/10000
...

内容协商:同一个资源可能有多种表现形式,如中文版和英文版,虽然本质的信息不一样,但是还是看作是同一个资源。在首部字段中的某些信息告知。

  • 服务器驱动协商:由服务器端根据首部字段自动处理
  • 客户端驱动协商:通过用户手动选择
  • 透明协商:某个中间代理代替客户端进行协商

第四章 HTTP 状态码

客户端通过状态码得知服务器端返回的请求结果,但是状态码和实际情况并不一定一致,这源于大家并没有严格遵守规定。

状态码类别:

  • 1XX:信息类状态码
  • 2XX:成功状态码
    • 200 OK:请求正常处理
    • 204 No Content:请求成功,但无数据返回,只有通知
    • 206 Partial Content:范围请求的成功返回
  • 3XX:重定向状态码,会在响应报文中附带 Location,指向新的 URI,通常都会把 POST 改为 GET,并删除主体再次发送请求。
    • 301 Moved Permanently:请求的资源已永久被分配新的 URI,请求会自动转到新 URI,希望用户以后都用新的 URI
    • 302 Found:临时重定向和 301 类似,但是希望用户只本次使用新的 URI。许多浏览器将 302 视为 303
    • 303 See Other:会使浏览器用 GET 方法访问响应报文中 Location 中的 URI
    • 304 Not Modified:资源存在,但请求不满足要求(附带条件),虽然在3XX系列中,但和重定向没关系
    • 307 Temporary Redirect:和 302 一样,但是禁止从 POST 变成 GET
  • 4XX:客户端错误状态码
    • 400 Bad Request:无法理解请求,通常是语法错误
    • 401 Unauthorized:用户不被授权(用户信息不对)
    • 403 Forbidden:请求访问被拒,无权限
    • 404 Not Found:找不到资源
  • 5XX:服务器错误状态码
    • 500 Internal Server Error:服务端执行请求发生错误
    • 503 Service Unavailable:停机维护或超负载,无法处理请求

第五章 Web 服务器

一台物理服务器上可以运行多个虚拟服务器,当一台物理服务器上部署多个域名,这些域名都会解析到同一个IP地址上,此时就需要区分是发向哪个网站的请求。
所以需要在发送 HTTP 请求时,在 Host 首部完整指定主机名或域名,让服务器来辨别。

  • 代理:作为客户端和服务端的中间者,代替客户端向服务端发出请求,并将服务端的响应转发给客户端
  • 网关:转发数据的服务器
  • 隧道:客户端与服务端的一条通信线路,通常配套上一些加密手段,例如 SSL,保证通信的安全
  • 源服务器:拥有资源的服务器,即最终取得资源的地方
  • 代理服务器:作为代理负责转发请求
    • 缓存代理:将源服务器的资源副本保存在本地,替源服务器完成资源的响应(资源存在有效期限,缓存服务器也会时不时同步资源信息)
    • 透明代理:不对报文做任何处理,好像不存在,只负责转发
  • 网关:和代理类似,但是可以桥接非HTTP的源服务器,和与源服务器完成非HTTP的协议通信
  • 客户端缓存:客户端对源服务器取得的资源在本地进行缓存,一般作为临时网络文件

第六章 HTTP 首部

关于首部字段的内容,大体有个印象都能干什么就行,由于字段内容非常多,本书也没有详细展开,用到的时候还是需要查阅相关的工具书或资料

首部字段格式:首部字段名: 字段值, 字段值2...,可以有多个字段值

如果首部字段重复,不同的浏览器可能有不同的处理方式,并没有一个规定

HTTP 首部字段:

  • 通用首部字段:请求报文和响应报文都会使用
  • 请求首部字段:请求报文使用,包含请求的附加内容
  • 响应首部字段:响应报文使用,包含响应的附加内容
  • 实体首部字段:实体部分的信息,例如更新时间

End-to-end 首部:端到端首部,首部必须到达客户端或服务端
Hop-by-hop 首部:逐跳首部,可能会因为代理或缓存而不再转发

通用首部字段:

  • Cache-Control 首部字段:用于控制缓存,有分为缓存请求指令和缓存响应指令
    • max-age:缓存有效期
    • min-fresh:要求缓存的更新时间必须小于该值
    • public:其他用户也可缓存
    • private:只有特定用户可以缓存
    • no-cache:不缓存过期的资源,缓存代理会向源服务器确认资源信息
    • no-store:禁止缓存
    • max-stale:最大可接受的缓存时间,即使过期,但是不超过该值仍然接收
    • only-if-cached:只会从缓存服务器中获取资源,如果缓存中不存在该资源,不会向源服务器发送请求,返回 504
    • must-revalidate:要求缓存代理向源服务器确认资源有效性,如果无法从源服务器获取资源,返回 504
    • proxy-revalidate:要求所有缓存服务器必须对响应的资源验证有效性
    • no-transform:无论请求还是响应,不能改变实体主体的媒体类型,例如可以防止缓存或代理压缩图片
  • Connection首部字段:
    • 控制某个首部字段不再转发,即下次发出前,删除该首部字段 Connection: 不再转发的字段名
    • 管理持久连接:Connection: close,取消持久连接;Connection: Keep-Alive,持久连接
  • Date:创建 HTTP 报文的日期和时间
  • Pragma:历史遗留字段,Pragma: no-cacheCache-Control: no-cache,针对非HTTP/1.1的服务器。为了实现兼容性,会同时发送这两条指令确保各个服务器都能执行
  • Trailer:在报文主体之后的首部字段,分块传输编码相关
  • Transfer-Encoding:规定了传输报文主体的编码方式,在 HTTP/1.1 中只对分块传输编码有效
  • Upgrade:检测 HTTP 协议及其他协议是否可以使用更高的版本,参数可以用来指定即使是一个完全不同的协议
  • Via:追踪传输路径,途径服务器会在该字段留下记录信息
  • Warning:Warning: [警告码][警告主机:端口号][警告内容][日期时间]

请求首部字段:附加信息、客户端信息、相应内容相关的优先级等

  • Accept:通知可接受的类型,如果可接收多种类型,可以设置优先级
  • Accept-Charset:通知字符集,可设置优先级
  • Accept-Encoding:通知支持的内容编码,可设置优先级,例如 gzip 压缩编码,* 代表任意编码格式
  • Accept-Language:通知支持的语言,可设置优先级
  • Authorization:告知服务器认证信息,通常在服务器要求认证之后再发送请求时附带
  • Expect:表达期望某种行为,如果服务器无法理解,返回 417 Expectation Failed
  • From:告诉服务器用户的电子邮箱地址
  • Host:告诉服务器互联网主机名和端口号,必须包含该字段,针对同一个物理服务器有多个域名的虚拟主机
  • If-xxx:条件请求,服务器接受到该类型的请求后,只有条件为真才会接受请求
    • If-Match:字段值和 ETag(实体标记)匹配时,响应请求
    • If-Modified-Since:资源在字段值的日期之后更新,响应请求
    • If-None-Match:与 If-Match 作用相反
    • If-Range:如果满足字段值,则作为范围请求处理,如果不满足,则返回全部资源
    • If-Unmodified-Since:与 If-Modified-Since 作用相反
  • Max-Forwards:设定可经过服务器的最大值,每经过一个服务器减一,为 0 时不再转发,通常用于 Debug
  • Proxy-Authorization:与 Authorization 不同的是,该认证发生在代理和客户端之间
  • Range:指定资源的请求范围,不获取完整的资源
  • Referer:告知服务器请求的原始资源的 URI,但有时候 URI 包含敏感信息,就不用该字段了
  • TE:告知服务器能够处理的传输编码方式及优先级
  • User-Agent:浏览器和用户代理信息,通常用于区分各类设备

响应首部字段:

  • Accept-Ranges:告知客户端能否支持范围请求
  • Age:源服务器响应后过了多少时间
  • ETag:标识资源实体,具有唯一性,资源更新时 ETag 也会随之更改
    • 强ETag:任何修改都会改变值
    • 弱ETag:只有资源发生根本更改时才会改变
  • Location:将客户端引导至新的 URI,一般用于配合重定向
  • Proxy-Authenticate:通知客户端所要求的认证信息,但是只发生在代理和客户端之间
  • Retry-After:通知客户端多久之后再发送请求
  • Server:记录服务器安装的 HTTP 应用程序的信息
  • Vary:同一个资源可能有多个版本,如果Vary指定的字段不同,则必须重新从源服务器获取。例如Vary: Accept-Language,可能存在多个语言版本,指定 Accep-Language 必须相同才能返回资源
  • WWW-Authenticate:用于 HTTP 访问认证,用于对用户进行认证

实体首部字段:

  • Allow:告知客户端所支持的HTTP方法 Allow: GET, HEAD
  • Content-Encoding:告知客户端实体的主体部分的内容编码方式
  • Content-Language:告知客户端所使用的语言
  • Content-Length:资源大小
  • Content-Location:报文主体部分的 URI,有可能请求一个资源但是有不同版本,根据首部字段信息,返回一个不同的 URI,此时记录在该字段中。例如访问 http://www.hackr.jp/ 返回 http://www.hackr.jp/index-zh.html
  • Content-MD5:对报文主体执行 MD5 算法,与该字段比较,确认资源完整性和有效性
  • Content-Range:告知客户端返回资源的范围
  • Content-Type:说明实体主体的媒体类型
  • Expires:告知客户端资源失效的日期和时间
  • Last-Modified:资源最后修改的时间

为Cookie服务的首部字段:
Set-Cookie:响应首部字段,发送给客户端,开始状态管理

  • NAME=VALUE:Cookie 的名称和值
  • expires=DATE:Cookie 的有效期,不指定则默认到浏览器关闭为止
  • path=PATH:对应的路径内的页面可以访问该 cookie
  • domain=域名:不用域名可以访问同一 cookie
  • Secure:仅在 HTTPS 下才发送 Cookie
  • HttpOnly:禁止 JavaScript 脚本的访问
  • Cookie: status=enable:告知服务器,客户端想开启状态管理支持,并在请求中发送从服务器接受到的 cookie

其他首部字段:

  • X-Franme-Options:控制网站内容在其他网站的 Frame 标签下的显示问题(嵌套显示,在别的网站内显示该网站)
    • DENY:拒绝
    • SAMEORIGIN:仅同源域名下的页面支持
  • X-XSS-PRotection:0-关闭XSS过滤设置;1-开启XSS过滤设置
  • DNT(Do Not Track):0-同意被追踪;1-拒绝被追踪
  • P3P:用于保护用户隐私

第七章 HTTPS

HTTP的缺点:

  • 通信使用明文,被窃听
  • 不验证身份
  • 无法验证报文完整性,被篡改

TCP/IP 网络并不保证安全不被窃听

HTTPS = HTTP + SSL,对通信进行加密

对内容进行加密:对报文主体进行加密后再发送,要求客户端和服务端有加密和解密的能力

不验证身份的弊端:

  • 客户端不知道接受的响应是否真实,服务端可能是伪装的
  • 服务端不知道发来的请求是否真实,客户端可能是伪装的
  • 无法确定对方是否具备权限
  • 无法阻止无意义的请求,DoS攻击

SSL证书:验证双方的身份,对通信进行加密

HTTP + 加密 + 认证 + 完整性保护 = HTTPS
HTTPS并不是新协议,只是通信接口套用了 SSL 和 TLS

对称密钥加密:加密解密同用一个密钥,算力要求低
非对称密钥加密:使用公钥加密,使用私钥解密,算力要求高

HTTPS 使用混合加密方式,通过非对称密钥加密对称密钥,最后使用对称密钥来加解密通信信息

为了防止公钥在传输过程中被篡改,引入数字证书认证,即将证书与公钥绑定在一起,证书证实该密钥为真

HTTPS的安全通信机制:

  • 客户端:发送 hello 报文请求开始 SSL 通信
  • 服务端:响应 hello 报文,接受 SSL 通信;发送证书和公钥;最后发送 hello done 报文,通知 SSL 通信握手协商结束
  • 客户端:发送用公钥加密的密钥;通知服务器使用该密钥进行加密;最后发送 Finished 报文
  • 服务端:通知客户端使用先前密钥进行加密;发送 Finished 报文
  • SSL链接建立!
  • 开始发送 HTTP 报文
  • 客户端断开连接,发送 close_notify 报文

SSL 的弊端:
由于 SSL 需要进行额外的报文处理,会消耗 CPU 和内存资源,导致网络负载变大。另一方面 SSL 需要加解密计算,也会进一步消耗资源

第八章 用户身份的认证

HTTP 的认证方式:

  • BASIC 认证
  • DIGEST 认证
  • SSL 客户端认证
  • FormBase 认证

BASIC 认证:

  • 客户端:发送请求
  • 服务端:返回 401 要求认证
  • 客户端:发送 ID 和密码
  • 服务端:认证成功返回 200,否则返回 401

缺陷:可能被窃听,安全性低

DIGEST 认证:

  • 客户端:发送请求
  • 服务端:发送临时质询码,要求认证
  • 客户端:发送摘要(认证信息经过 MD5 或其他算法处理过后)及以质询码计算出的响应码
  • 服务端:认证成功返回 200,否则返回 401

避免窃听,但难以确认用户身份

SSL 客户端认证:

  • 客户端:发送请求
  • 服务端:发送 Certificate Request 报文,要求客户端证书
  • 客户端:发送证书
  • 服务端:使用证书内的公钥开始 HTTPS 通信

双因素认证:一是需要确认计算机无误(证书),另一是确认使用者是本人(其他信息)

基于表单的认证:这部分没有规定,各公司实现也不相同
使用 Cookie 来管理 Session:

  • 客户端:发送登录信息
  • 服务端:发送包含 Session ID 的 cookie
  • 客户端:发送包含 Session ID 的 cookie,保持状态

第九章 HTTP 追加协议

HTTP 本来是用来传输 HTML 文档的协议,但现在应用要求更多,就出现了各种基于 Web 应用和脚本的拓展

HTTP 的瓶颈:一条连接只能发送一个请求,为了实时更新内容,就需要一直访问服务器,在大量数据持久通信的情况下会造成性能浪费

Ajax 的解决方法:异步 JavaScript 和 XML
核心:XMLHttpRequest,只更新局部页面

Comet 的解决方法:延迟响应,接到请求后不会立刻应答,先处于挂起状态,等待满足某些条件之后才进行响应,模拟服务端向客户端推送信息
(通常情况下客户端向服务端发出请求才会收到回复,服务端是不会主动向客户端主动发出信息的,通过延迟响应的方式近似实现服务端向客户端主动发送信息)

SPDY(speed)出现,为了解决这一瓶颈:实际上并没有改写 HTTP 协议,而是新增了一层,规定 SPDY 通信必须使用 SSL

  • 多路复用流,所有请求都在一条 TCP 连接上完成
  • 赋予请求优先级:分配优先级顺序
  • 压缩 HTTP 首部
  • 推送功能:服务器可以直接向客户端发送推送,而不必等待请求
  • 服务器提示功能:服务器主动提示客户端请求所需的资源,客户端在使用该资源之前就知晓该资源的存在,在资源已缓存的情况下,可以避免一些通信

WebSocket 全双工通信:
Web 服务器和客户端建起 WebSocket 协议的连接之后,之后所有的通信都依靠这个协议

连接建立之后,服务器还是客户端都可以直接向对方发送报文

  • 实现服务端推送功能
  • 减少通信量:不需要每次通信都连接,发送首部信息

连接过程:握手请求->握手响应,之后就采用 WebSocket 数据帧,而不是 HTTP 的数据帧

WebDAV:分布式文件系统,对服务器上的内容直接进行复制、编辑等操作,是对服务器文件进行管理的协议
WebDAV 概念:

  • 集合:统一管理多个资源的概念
  • 资源:文件或集合
  • 属性:定义资源
  • 锁:文件操作权限

第十章 构建 Web 内容的技术

动态 HTML:直观来讲就是网页可以发生变化
使用 JavaScript 脚本语言实现动态 HTML,利用 DOM,使 HTML 中的元素发生变化
DOM(Document Object Model):用以操作 HTML 文档和 XML 文档的 API

Web 应用:通过程序创建 HTML

  • CGI(Common Gateway Interface):通用网关接口,将客户端的请求转发给程序,程序会作出相应的动作,例如 HTML 等动态内容
  • CGI 程序:Perl、PHP、Ruby、C
  • Servlet:创建 HTML 的程序,一种解决 CGI 问题的技术

CGI每次请求都会请求新的CGI程序,而Servlet运行在Web容器内,节省了资源

数据发布的格式及语言:

  • XML:可拓展标记语言,一种通用的标记语言,使数据共享更容易
  • RSS/Atom:一种用于信息推送、发布的技术
  • JSON:轻量级数据标记语言
上一篇 下一篇

评论 | 0条评论