这篇文章是学习中科大自动化系郑烇老师《计算机网络》MOOC的笔记。课程录像可以在 这里 观看,教材是《计算机网络-自顶向下方法(第7版)》,课件可以在 这里 下载。

本篇内容对应课程录像的 P14 2.2 Web and HTTP,欢迎讨论交流。

HTTP的工作方式

术语

对象 :一个html,一张图片,一段声音,web页面就可以看做由一系列对象组成。

URL :统一资源定位符(Unified Resources Locator),可以通过URL引用对象。

  • URL的格式:protocol://user:psw@www.xxx.com/some/some:port。如果是在未登录的情况下访问URL,则 user:psw@ 部分可以省略。
  • 访问网站时,浏览器一般先拿到base HTML文件,而其它文件如图片、音视频等则以URL的形式置于HTML元素中,当浏览器解析到这些URL时便会再按照它们请求对应的对象。

HTTP :超文本传输协议(HyperText Transmission Protocol),是web的应用层协议

  • HTTP协议的URL中protocolhttp,而port即端口号默认为80。

HTTP的工作流程

HTTP协议在实际执行的过程中依赖于传输层TCP协议提供的服务,具体可分为如下几步:

  • 客户端发起TCP连接请求
  • 服务端向客户端表示同意建立连接
  • 客户端发起HTTP传输请求
  • 服务端将客户端请求的对象封装成响应报文发给客户端
  • 客户端对收到的对象进行解析
  • 拆除TCP连接(包括拆除请求、确认请求)

HTTP连接时序关系示意

TCP的套接字(socket)在HTTP协议的实现中起到了关键作用。具体来讲,服务端本身具有一个守候socket,每当与一个客户端建立TCP连接,服务端都会创建一个新的连接socket,这样就可以很方便地管理服务端上所有的TCP连接。关于TCP套接字的具体细节,将在后续章节传输层对应内容中详细介绍。

HTTP1.1:持久、流水线

HTTP的最初版本——1.0版本是由IETF RFC 1945文档所确定的。时隔数月,RFC 2068文档进一步完善了HTTP协议,形成了HTTP1.1,也是当前最为流行的版本。HTTP1.1中加入了很多新的特性,其中比较重要的有两个:持久HTTP连接和流水线式请求,它们都对多个对象的同时传输至关重要。

持久HTTP连接指的在是一个TCP连接上先后传输多个HTTP对象。在HTTP1.0中,一个对象传输结束后,对应的TCP连接就将被自动关闭;而在持久连接的情况下,传输完一个对象后,TCP连接仍将被保持,等待下一个HTTP传输请求,直到超过一定时间或客户端主动发送拆除TCP连接的请求。
传输多个对象时非持久(左)与持久(右)连接的区别

往返时间round-trip time, RTT):一个小分组从客户端到服务端再到客户端的传播时间,传输时间忽略(假设分组极小)。

流水线式请求指的是同时有多个对象要请求时,不等当前请求的对象返回,即发送传输下一个对象的请求。这种情况下每个对象可能平均只花费1RTT的时间,而非流水线传输时,每个对象至少花费2RTT。
传输多个对象时非流水线(左)与流水线(右)的区别

HTTP报文

HTTP报文是客户端和服务端通过HTTP协议交换的实质性内容。所有HTTP报文都是以ASCII码的形式在应用层间传输的,这意味着报文具备高度的可读性。

HTTP请求报文

请求报文通用格式

  • 从上到下,请求报文分为请求行(request line),首部行(header lines)和实体(entity body)。首部行和实体之间有一回车符,不过实体部分并非所有报文都具备

  • 请求方法(method):有GET/POST/HEAD/PUT/DELETE五种

    • HEAD请求区别于GET的关键是只要求服务端返回HTML的头部(即<head></head>内包含的信息),主要用于网站维护和搜索引擎构建索引;
    • PUT和DELETE是HTTP1.1版本新增的,分别代表将实体主体中的文件上传至指定URL和从指定URL删除文件。这两个方法较为少用,主要应用于网站管理。
  • 协议版本(version):一般是HTTP/1.1的格式;

  • 首部行可以带有多个字段。

  • 若要向服务器提交内容,存在两种实现方式:

    • POST方法请求,提交的内容在实体部中;
    • GET方法请求,URL中以参数形式提交信息,如:http://www.baidu.com/s?wd=xx+yy+zzz&cl=3,参数之间以&分隔,参数名和值以=分隔。

HTTP响应报文

响应报文通用格式

  • 从上到下,响应报文依然分为状态行(status line),首部行(header lines)和实体(entity body),首部行和实体之间有一回车符,实体部分并非所有报文都具备

  • 状态码(status code):标志服务器对于收到的HTTP请求的反应,常见的状态码如200、301、404、500等;

  • 状态码解释(phrase):对于状态码含义的解释短语。如对于状态码200的解释为OK,代表正常响应。

首部常见字段

HTTP报文的首部(或称为头部)可以容纳多个字段,这些字段大体上可以分为通用首部字段请求首部字段响应首部字段实体首部字段四类。关于各类首部字段的详细解释,可以参考 这篇博文

常见状态码

HTTP协议使用状态码表示服务端对于请求的响应状态。状态码一般为三位数字,依据其首位,可以分为正在处理(1xx)正常处理(2xx)需进一步操作(3xx)无法处理(4xx)、**服务端出错(5xx)**五个大类。

常见状态码表及对应解释如下:

状态码 状态码英文名称 中文描述
100 Continue 继续。客户端应继续其请求
101 Switching Protocols 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议
200 OK 请求成功。一般用于GET与POST请求
201 Created 已创建。成功请求并创建了新的资源
202 Accepted 已接受。已经接受请求,但未处理完成
203 Non-Authoritative Information 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本
204 No Content 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档
205 Reset Content 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域
206 Partial Content 部分内容。服务器成功处理了部分GET请求
300 Multiple Choices 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择
301 Moved Permanently 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
302 Found 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI
303 See Other 查看其它地址。与301类似。使用GET和POST请求查看
304 Not Modified 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
305 Use Proxy 使用代理。所请求的资源必须通过代理访问
306 Unused 已经被废弃的HTTP状态码
307 Temporary Redirect 临时重定向。与302类似。使用GET请求重定向
400 Bad Request 客户端请求的语法错误,服务器无法理解
401 Unauthorized 请求要求用户的身份认证
402 Payment Required 保留,将来使用
403 Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求
404 Not Found 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
405 Method Not Allowed 客户端请求中的方法被禁止
406 Not Acceptable 服务器无法根据客户端请求的内容特性完成请求
407 Proxy Authentication Required 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权
408 Request Time-out 服务器等待客户端发送的请求时间过长,超时
409 Conflict 服务器完成客户端的 PUT 请求时可能返回此代码,服务器处理请求时发生了冲突
410 Gone 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置
411 Length Required 服务器无法处理客户端发送的不带Content-Length的请求信息
412 Precondition Failed 客户端请求信息的先决条件错误
413 Request Entity Too Large 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息
414 Request-URI Too Large 请求的URI过长(URI通常为网址),服务器无法处理
415 Unsupported Media Type 服务器无法处理请求附带的媒体格式
416 Requested range not satisfiable 客户端请求的范围无效
417 Expectation Failed 服务器无法满足Expect的请求头信息
500 Internal Server Error 服务器内部错误,无法完成请求
501 Not Implemented 服务器不支持请求的功能,无法完成请求
502 Bad Gateway 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
503 Service Unavailable 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
504 Gateway Time-out 充当网关或代理的服务器,未及时从远端服务器获取请求
505 HTTP Version not supported 服务器不支持请求的HTTP协议的版本,无法完成处理

维护状态的连接:cookies

HTTP协议在刚刚诞生时是不维护状态的。也就是说,服务器只负责处理接收到的请求这一件事,而不关心发送请求的客户端处于什么样的状态。这样的设计确保了HTTP协议的简洁和便利性,然而并不能满足日渐复杂的业务需求。为了使得服务器能够知晓当前建立连接的客户端的状态,cookies应运而生。

Cookies的工作原理是:

  • 服务器在第一次收到HTTP请求时,在响应报文中发送一个cookie,并将其存在本地的数据库或文件系统中。
  • 客户端收到响应后也将cookie存在本地内存或硬盘中,下次请求时带上该cookie。
  • 服务端将其与本地的cookie对比,便可识别出当前客户端的状态,并据此决定发送响应的内容。

为了实现cookies的传递,在HTTP报文的首部添加了set-cookiecookie两个字段。cookie本身也可以在一次响应中同时设置多个。

Cookies在为web应用带来方便的同时,也衍生出一些问题,其中最受关注的就是cookies与隐私的关系:cookies能够记录大量与用户行为相关的信息,这可能导致cookies中的信息被过度使用或泄露给第三方。

web缓存

对于较大的数据,如果每次都访问原始服务器获取,则会导致传输时间较长。一种有效的解决方案是类比CPU中缓存的设计,通过在局域网内设置一个代理服务器,在向原始服务器请求报文时同时缓存到本地,下次请求时可以直接从本地返回(称为命中)。web缓存机制的存在可以使得网络在不访问原始服务器的情况下满足客户端请求。
web缓存的好处在于:

  • 客户端访问网站更快了
  • 服务端的压力减轻了
  • 网络的流量负担也变小了

缓存代理一般由ISP安装(如:学校、公司、居民区等),为了避免原始服务器修改对象导致缓存过时,HTTP实现了“条件式获取”机制。关于HTTP web缓存的具体细节,可以参考 这篇博文 的介绍。相关流程图如下:

HTTP Web缓存获取机制