HTTP协议

HTTP协议(HyperText Transfer Protocol,超文本传输协议),是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信的基础。

HTTP协议和TCP/IP协议族内的其他众多的协议相同,用于客户端和服务器之间的通信。

HTTP协议规定,请求从客户端发出,最后服务器端响应该请求并返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应。

无状态

HTTP是一种不保存状态,即无状态(stateless)协议。HTTP协议自身不对请求和响应之间的通信状态进行保存。也就是说在HTTP这个级别,协议对于发送过的请求或响应都不做持久化处理。

可以理解为,浏览器发送请求给服务器时,服务器响应请求;但同一个浏览器再次请求时,服务器不知道这次请求的浏览器是否为上次那个浏览器,也就是服务器没有记忆浏览器的特征。

无状态的状态是啥

举个例子,老王在隔壁开了一家饭店,小明听说后就想尝尝这家饭店的手艺。吃完觉得还不错,决定明天再去。

第二天,小明又去了饭店,结账的时候跟老板说:我昨天来消费过,今天可否给个优惠?

无状态(stateless)

老板答:你昨天来过吗?我没有印象了,抱歉不能给你优惠。

有状态(Stateful)

为了更好地吸引老顾客,维护好客源,老板决定把每个顾客记录下来。

老板答:奥,稍等让我查一下记录……原来是你啊,行,给你88折,欢迎下次惠顾!

总结

由上可知,这个状态就是客户端的状态。

Cookie和Session

如何保存客户端的状态?实现的方式有两种,分别是Cookie和Session。

Cookie是通过客户端保持状态的解决方案。

从定义上来说,Cookie就是由服务器发给客户端的特殊信息,而这些信息以文本文件的方式存放在客户端,然后客户端每次向服务器发送请求的时候都会带上这些特殊的信息。

Session

Session是通过服务器来保持状态的。

Session指的是服务器端为客户端所开辟的存储空间,在其中保存的信息就是用于保持状态。

客户端第一次访问时,服务器会为这个客户端创建唯一特征码,也就是SessionID,客户端再次请求的时候,服务器会根据SessionID在服务端的数据库中查询,若有这个SessionID,则会做出相应响应。

HTTP报文

用于HTTP协议交互的信息被称为HTTP报文。请求端(客户端)的HTTP报文叫做请求报文,响应端(服务器端)的叫做响应报文。HTTP报文本身是由多行(用CR+LF作换行符)数据构成的字符串文本。

HTTP报文大致可分为报文首部报文主体两块。两者由最初出现的空行(CR+LF)来划分。通常,并不一定要有报文主体。

image-20200815110029323

请求报文和响应报文的首部内容由以下数据组成:

  • 请求行:包含用于请求的方法,请求URI和HTTP版本。
  • 状态行:包含表明响应结果的状态码,原因短语和HTTP版本。
  • 首部字段:包含表示请求和响应的各种条件和属性的各类首部。一般有4种首部,分别是:通用首部、请求首部、响应首部和实体首部。
  • 其他:可能包含HTTP的RFC里未定义的首部(Cookie等)。

HTTP状态码

状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果。借助状态码,用户可以知道服务器端是正常处理了请求,还是出现了错误。

image-20200815110505651

状态码如200 OK,以3位数字和原因短语组成。数字中的第一位指定了响应类别,后两位无分类。响应类别有以下5种。

image-20200815110545928

常见状态码说明:

状态码 说明
200 OK 表示从客户端发来的请求在服务器端被正常处理了。
204 No Content 该状态码代表服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分。
206 Partial Content 该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求。响应报文中包含由Content-Range指定范围的实体内容。
301 Moved Permanently 永久性重定向。该状态码表示请求的资源已被分配了新的URI,以后应使用资源现在所指的URI。
302 Found 临时性重定向。该状态码表示请求的资源已被分配了新的URI,希望用户(本次)能使用新的URI访问。
303 See Other 该状态码表示由于请求对应的资源存在着另一个URI,应使用GET方法定向获取请求的资源。
304 Not Modified 该状态码表示客户端发送附带条件的请求时,服务器端允许请求访问资源,但因发生请求未满足条件的情况后,直接返回304 Not Modified(服务器端资源未改变,可直接使用客户端未过期的缓存)。
307 Temporary Redirect 临时重定向。该状态码与302 Found有着相同的含义。尽管302标准禁止POST变换成GET,但实际使用时大家并不遵守。
400 Bad Request 该状态码表示请求报文中存在语法错误。当错误发生时,需修改请求的内容后再次发送请求。
401 Unauthorized 该状态码表示发送的请求需要有通过HTTP认证(BASIC认证、DIGEST认证)的认证信息。
403 Forbidden 该状态码表明对请求资源的访问被服务器拒绝了。
404 Not Found 该状态码表明服务器上无法找到请求的资源。除此之外,也可以在服务器端拒绝请求且不想说明理由时使用。
500 Internal Server Error 该状态码表明服务器端在执行请求时发生了错误。也有可能是Web应用存在的bug或某些临时的故障。
503 Service Unavailable 该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。

通信数据转发程序

HTTP通信时,除客户端和服务器以外,还有一些用于通信数据转发的应用程序,例如代理、网关和隧道。它们可以配合服务器工作。

代理

代理服务器的基本行为就是接收客户端发送的请求后转发给其他服务器。代理不改变请求URI,会直接发送给前方持有资源的目标服务器。

代理不改变请求URI,会直接发送给前方持有资源的目标服务器。持有资源实体的服务器被称为源服务器。从源服务器返回的响应经过代理服务器后再传给客户端。

使用代理服务器的理由有:利用缓存技术减少网络带宽的流量,均衡源服务器的负载(负载均衡),组织内部针对特定网站的访问控制,以获取访问日志为主要目的,等等。

缓存代理

代理转发响应时,缓存代理(Caching Proxy)会预先将资源的副本(缓存)保存在代理服务器上。

当代理再次接收到对相同资源的请求时,就可以不从源服务器那里获取资源,而是将之前缓存的资源作为响应返回。

透明代理(透传)

转发请求或响应时,不对报文做任何加工的代理类型被称为透明代理(Transparent Proxy)。反之,对报文内容进行加工的代理被称为非透明代理。

网关

网关的工作机制和代理十分相似。而网关能使通信线路上的服务器提供非HTTP协议服务。利用网关能提高通信的安全性,因为可以在客户端与网关之间的通信线路上加密以确保连接的安全。比如,网关可以连接数据库,使用SQL语句查询数据。另外,在Web购物网站上进行信用卡结算时,网关可以和信用卡结算系统联动。

隧道

道可按要求建立起一条与其他服务器的通信线路,届时使用SSL等加密手段进行通信。隧道的目的是确保客户端能与服务器进行安全的通信。隧道本身不会去解析HTTP请求。也就是说,请求保持原样中转给之后的服务器。隧道会在通信双方断开连接时结束。

HTTP首部

HTTP首部字段根据实际用途被分为以下4种类型:

  • 通用首部字段(General Header Fields)请求报文和响应报文两方都会使用的首部。
  • 请求首部字段(Request Header Fields)从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、响应内容相关优先级等信息。
  • 响应首部字段(Response Header Fields)从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。
  • 实体首部字段(Entity Header Fields)针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。

HTTP/1.1首部字段

通用首部字段(General)

image-20200826142126658

请求首部字段(Request Headers)

image-20200826142319658

响应首部字段(Response Headers)

image-20200826142538361

实体首部字段

image-20200826142734457

非HTTP/1.1首部字段

在HTTP协议通信交互中使用到的首部字段,不限于RFC2616中定义的47种首部字段。还有Cookie、Set-Cookie和Content-Disposition等在其他RFC中定义的首部字段,它们的使用频率也很高。这些非正式的首部字段统一归纳在RFC4229 HTTP Header Field Registrations中。