HTTP协议原理

783 阅读8分钟

HTTP协议

http 通信协议的基本原理

  • http 协议在远程通信场景中的应用还是挺广泛的,包括现在主流的微服务架构的通信都是基于http协议。

  • 一次 HTTP 请求的通信流程

DNS

DNS: (Domain Name System)服务是和 HTTP 协议一样位于应用层的协议。它提供域名到 IP地址之间的解析服务, 用户通常使用主机名或域名来访问对方的计算机,而不是直接通过IP地址访问。

因为与 IP 地址的一组纯数字相比,用字母配合数字的表示形式来指定计算机名更符合人的记忆习惯 但要让计算机去理解名称,相对而言就变得困难了。因为计算机更擅长处理一长数字。为 了解决上述的问题,DNS 服务应运而生。DNS 协议提供通过域名查找 IP 地址,逆向从 IP 地址反查域名的服务。

HTTP 通信协议的组成

我们应该知道 HTTP 协议是基于应用层 的协议,并且在传输层使用的TCP的可靠性通信协议。既然是协议,那么就应该符合协议的定义。

定义:协议是两个需要通过网络通信的程序达成的一种约定,它规定了报文的交换方式和包含的意义。

URL

  • URI 用字符串标识某一互联网资源,而 URL 表示资源的地点(互联网上所处的位置)。可见 URL 是 URI 的子集。

  • www.study.com:8080/java/index.…

  • schema://host[:port#]/path/.../?[url-params]#[query-string]

  1. scheme:指定应用层使用的协议(http, https, ftp)
  2. host:HTTP 服务器的 IP 地址或者域名
  3. port:HTTP 服务器的默认端口是 80,这种情况下端口号可以省略。如果使用了别的端口,必须指明,例如 www.cnblogs.com:8080/
  4. path:访问资源的路径
  5. url-params:显示传递的参数值
  6. query-string:查询字符串,'#'片段标识符(使用片段标识符通常可标记出已获取资源中的子资源(文档内的某个位置))
  • 通过这个 url 地址,我们就可以读到,当前用户要使用 http 协议访问指定服务器上对应进程中的资源,并且携带了请求参数。

MIME Type

服务器根据用户请求的资源找到对应的文件以后,会返回一个资源给到客户端浏览器,浏览 器会对这个资源解析并且渲染。但是服务器上的资源类型有很多,比如图片类型、视频类型、 Js、Css、文本等。MIME Type:是描述消息内容类型的因特网标准,常见的几种类型

  1. 文本文件:text/html,text/plain,text/css,application/xhtml+xml,application/xml
  2. 图片文件:image/jpeg,image/gif,image/png.
  3. 视频文件:video/mpeg,video/quicktime

我们可以通过两种方式来设置文件的渲染类型,第一种是Accept,第二种是Content-Type

  1. Accept: 表示客户端希望接受的数据类型,即告诉服务器我需要什么媒体类型的数据,此时 服务器应该根据Accept请求头生产指定媒体类型的数据
  2. Content-Type: 表示发送端发送的实体数据类型,比如我们应该写过类似的: resposne.setContentType(“application/json;charset=utf-8”)的代码,表示服务端返回的数据格式是json。

如果Accept和Content-Type不一致,假如说Accept要接收的类型是image/gif,但是服务端返回的数据是text/html,那么浏览器将会无法解析,从而产生错误。

状态码

  • 状态码的职责是当客户端向服务端发送请求时,描述服务端返回的请求处理结果,通过状态码,浏览器可以知道服务器是正常处理请求还是出现了错误。 常见的状态码:
  1. 200:一切正常
  2. 301:永久重定向
  3. 404:请求资源不存在
  4. 500:服务端内部错误

有了状态码,在用户访问某个网站出现非正常状态时,浏览器就可以很友好的提示用户

URL提交方法

  • 通过postMan测试的时候就可以用到提交方式 有了url,mimetype、状态码, 能够基本满足用户的需求,但是,很多时候一个网站不单纯只是不断从服务端获取资源并做渲染,可能还需要做一些数据的提交、删除等功能。所以浏览器定义了8种方法来表示对于不同请求的操作方式,当然最常用的还是Get和Post。
  1. GET:一般是用于客户端发送一个 URI 地址去获取服务端的资源(一般用于查询作),Get 不支持的传输数据有限制,具体限制由浏览器决定
  2. POST:一般用户客户端传输一个实体给到服务端,让服务端去保存(一般用于创建操作)
  3. PUT:向服务器发送数据,一般用于更新数据的操作
  4. DELETE:客户端发起一个Delete请求要求服务端把某个数据删除(一般用于删除操作) 5. HEAD:获得报文首部
  5. OPTIONS:询问支持的方法
  6. TRACE:追踪路径
  7. CONNECT:用隧道协议连接代理

在 REST 架构风格中,有严格规定对于不同的请求类型要设置合适的请求方法。也是避免出现因为乱用导致混乱的问题。

请求报文

  • 请求报文格式包含三个部分,(起始行、首部字段、主体)

响应报文

  • 完整的信息

建立连接

  • 在最早的http协议中,每进行一次http通信,就需要做一次tcp的连接。而一次连接需要进行3次握手,这种通信方式会增加通信量的开销。

所以在HTTP/1.1中改用了持久连接,就是在一次连接建立之后,只要客户端或者服务端没有明确提出断开连接,那么这个tcp连接会一直保持连接状态

持久连接的一个最大的好处是:大大减少了连接的建立以及关闭时延。

HTTP1.1中有一个Transport段。会携带一个 Connection:Keep-Alive,表示希望将此条连接作为持久连接。

HTTP/1.1持久连接在默认情况下是激活的,除非特别指明,否则HTTP/1.1假定所有的连接都是持久的,要在事务处理结束之后将连接关闭,HTTP/1.1应用程序必须向报文中显示地添加 一个Connection:close首部。 HTTP1.1客户端加载在收到响应后,除非响应中包含了Connection:close首部,不然HTTP/1.1 连接就仍然维持在打开状态。但是,客户端和服务器仍然可以随时关闭空闲的连接。不发送 Connection:close并不意味这服务器承诺永远将连接保持在打开状态。

管道化连接: http/1.1允许在持久连接上使用请求管道。以前发送请求后需等待并收到响应, 才能发送下一个请求。管线化技术出现后,不用等待响应亦可直接发送下一个请求。这样就能够做到同时并行发送多个请求,而不需要一个接一个地等待响应了。

Http 协议的特点

Http 无状态协议

HTTP 协议是无状态的,什么是无状态呢?就是说 HTTP 协议本身不会对请求和响应之间的 通信状态做保存。 但是现在的应用都是有状态的,如果是无状态,那这些应用基本没人用,你想想,访问一个电商网站,先登录,然后去选购商品,当点击一个商品加入购物车以后又提示你登录。这种用户体验根本不会有人去使用。那我们是如何实现带状态的协议呢?

客户端支持的 cookie

Http 协议中引入了 cookie 技术,用来解决 http协议无状态的问题。通过在请求和响应报文中写入Cookie 信息来控制客户端的状态;Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存 Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。

服务端支持的 session

服务端是通过什么方式来保存状态的呢? 在基于tomcat这类的jsp/servlet容器中,会提供 session这样的机制来保存服务端的对象状态,服务器使用一种类似于散列表的结构来保存信息,当程序需要为某个客户端的请求创建一个 session 的时候,服务器首先检查这个客户端的请求是否包含了一个session标识- session id;

如果已包含一个session id 则说明以前已经为客户端创建过session,服务器就按照session id 把这个session检索出来使用(如果检索不到,会新建一个); 如果客户端请求不包含sessionid,则为此客户端创建一个session并且生成一个与此session 相关联的 session id, session id 的值是一个既不会重复,又不容易被找到规律的仿造字符 串,这个session id 将会返回给客户端保存

Tomcat处理seesion的源码

把session中的值放入cookie中,下次在接受同一个ip的请求时,就会重新拿到cookie的值。

session的生命周期 第一次请求---浏览器关闭