推荐查看文章:https://mp.weixin.qq.com/s?__biz=MzkwODIwMDY2OQ==&mid=2247488300&idx=1&sn=f2165ef48e47ee894cb95bc4b0d30346&source=41#wechat_redirect

一、键入网址按下回车会发生什么

HTTP 请求过程:

  • 浏览器从地址栏的输入中获得服务器的 IP 地址和端口号;
  • 浏览器用 TCP 的三次握手与服务器建立连接;
  • 浏览器向服务器发送拼好的报文;
  • 服务器收到报文后处理请求,同样拼好报文再发给浏览器;
  • 浏览器解析报文,渲染输出页面。

域名解析:
域名解析的过程中会有多级的缓存,浏览器首先看一下自己的缓存里有没有,如果没有就向操作系统的缓存要,还没有就检查本机域名解析文件 hosts

CDN:
因为 CDN 会缓存网站的大部分资源,比如图片、CSS 样式表,所以有的 HTTP 请求就不需要再发到网站,CDN 就可以直接响应你的请求,把数据发给你。 PHP、Java 等后台服务动态生成的动态资源,CDN 无法缓存。

小结:

  1. HTTP 协议基于底层的 TCP/IP 协议,所以必须要用 IP 地址建立连接;
  2. 如果不知道 IP 地址,就要用 DNS 协议去解析得到 IP 地址,否则就会连接失败;
  3. 建立 TCP 连接后会顺序收发数据,请求方和应答方都必须依据 HTTP 规范构建和解析报文;
  4. 为了减少响应时间,整个过程中的每一个环节都会有缓存,能够实现“短路”操作;
  5. 虽然现实中的 HTTP 传输过程非常复杂,但理论上仍然可以简化成实验里的“两点”模型。

二、HTTP报文是什么样子的?

HTTP 协议的请求报文和响应报文的结构基本相同,由三大部分组成:

  • 起始行(start line):描述请求或响应的基本信息;(请求头”或“响应头
  • 头部字段集合(header):使用 key-value 形式更详细地说明报文;
  • 消息正文(entity):实际传输的数据,它不一定是纯文本,可以是图片、视频等二进制数据。(实体)

image.png

请求行由三部分构成:

  • 请求方法:是一个动词,如 GET/POST,表示对资源的操作;
  • 请求目标:通常是一个 URI,标记了请求方法要操作的资源;
  • 版本号:表示报文使用的 HTTP 协议版本。

image.png

状态行也是由三部分构成

  • 版本号:表示报文使用的 HTTP 协议版本;
  • 状态码:一个三位数,用代码的形式表示处理的结果,比如 200 是成功,500 是服务器错误;
  • 原因:作为数字状态码补充,是更详细的解释文字,帮助人理解原因。

image.png

小结:

  • HTTP 报文结构就像是“大头儿子”,由“起始行 + 头部 + 空行 + 实体”组成,简单地说就是“header+body”;
  • HTTP 报文可以没有 body,但必须要有 header,而且 header 后也必须要有空行;
  • 请求头由“请求行 + 头部字段”构成,响应头由“状态行 + 头部字段”构成;
  • 请求行有三部分:请求方法,请求目标和版本号;
  • 状态行也有三部分:版本号,状态码和原因字符串;
  • 头部字段是 key-value 的形式,用“:”分隔,不区分大小写,顺序任意,除了规定的标准头,也可以任意添加自定义字段,实现功能扩展;
  • HTTP/1.1 里唯一要求必须提供的头字段是 Host,它必须出现在请求头里,标记虚拟主机名。

三、理解请求方法

1.常见的请求方法

  • GET:获取资源,可以理解为读取或者下载数据;
  • HEAD:获取资源的元信息;
  • POST:向资源提交数据,相当于写入或上传数据;
  • PUT:类似 POST;
  • DELETE:删除资源;
  • CONNECT:建立特殊的连接隧道;
  • OPTIONS:列出可对资源实行的方法;
  • TRACE:追踪请求 - 响应的传输路径。

1.1 GET

它的含义是请求从服务器获取资源,这个资源既可以是静态的文本、页面、图片、视频,也可以是由 PHP、Java 动态生成的页面或者其他格式的数据。

1.2 HEAD

HEAD方法与 GET 方法类似,也是请求从服务器获取资源,服务器的处理机制也是一样的,但服务器不会返回请求的实体数据,只会传回响应头,也就是资源的“元信息”。

1.3 POST/PUT

POST 也是一个经常用到的请求方法,使用频率应该是仅次于 GET,应用的场景也非常多,只要向服务器发送数据,用的大多数都是 POST。

PUT 的作用与 POST 类似,也可以向服务器提交数据,但与 POST 存在微妙的不同,通常 POST 表示的是“新建”“create”的含义,而 PUT 则是“修改”“update”的含义。

1.4 其他方法

DELETE方法指示服务器删除资源,因为这个动作危险性太大,所以通常服务器不会执行真正的删除操作,而是对资源做一个删除标记。当然,更多的时候服务器就直接不处理 DELETE 请求。

CONNECT是一个比较特殊的方法,要求服务器为客户端和另一台远程服务器建立一条特殊的连接隧道,这时 Web 服务器在中间充当了代理的角色。

OPTIONS方法要求服务器列出可对资源实行的操作方法,在响应头的 Allow 字段里返回。它的功能很有限,用处也不大,有的服务器(例如 Nginx)干脆就没有实现对它的支持。

TRACE方法多用于对 HTTP 链路的测试或诊断,可以显示出请求 - 响应的传输路径。它的本意是好的,但存在漏洞,会泄漏网站的信息,所以 Web 服务器通常也是禁止使用。

1.5 GET和POST的区别

  • 缓存的角度,GET 请求会被浏览器主动缓存下来,留下历史记录,而 POST 默认不会。
  • 编码的角度,GET 只能进行 URL 编码,只能接收 ASCII 字符,而 POST 没有限制。
  • 参数的角度,GET 一般放在 URL 中,因此不安全,POST 放在请求体中,更适合传输敏感信息。
  • 幂等性的角度,GET幂等的,而POST不是。(幂等表示执行相同的操作,结果也是相同的)
  • TCP的角度,GET 请求会把请求报文一次性发出去,而 POST 会分为两个 TCP 数据包,首先发 header 部分,如果服务器响应 100(continue), 然后发 body 部分。(火狐浏览器除外,它的 POST 请求只发一个 TCP 包)

2. 安全与幂等

所谓的“安全”是指请求方法不会“破坏”服务器上的资源,即不会对服务器上的资源造成实质的修改。 GET 和 HEAD 方法是“安全”的,因为它们是“只读”操作,只要服务器不故意曲解请求方法的处理方式,无论 GET 和 HEAD 操作多少次,服务器上的数据都是“安全的”。

幂等”是多次执行相同的操作,结果也都是相同的,即多次“幂”后结果“相等”。GET 和 HEAD 既是安全的也是幂等的,DELETE 可以多次删除同一个资源,效果都是“资源不存在”,所以也是幂等的。

小结

  • 请求方法是客户端发出的、要求服务器执行的、对资源的一种操作;
  • 请求方法是对服务器的“指示”,真正应如何处理由服务器来决定;
  • 最常用的请求方法是 GET 和 POST,分别是获取数据和发送数据;
  • HEAD 方法是轻量级的 GET,用来获取资源的元信息;
  • PUT 基本上是 POST 的同义词,多用于更新数据;
  • “安全”与“幂等”是描述请求方法的两个重要属性,具有理论指导意义,可以帮助我们设计系统。

四、你能写出正确的网址吗?

  • URI 是用来唯一标记服务器上资源的一个字符串,通常也称为 URL;
  • URI 通常由 scheme、host:port、path 和 query 四个部分组成,有的可以省略;
  • scheme 叫“方案名”或者“协议名”,表示资源应该使用哪种协议来访问;
  • “host:port”表示资源所在的主机名和端口号;
  • path 标记资源所在的位置;
  • query 表示对资源附加的额外要求;
  • 在 URI 里对“@&/”等特殊字符和汉字必须要做编码,否则服务器收到 HTTP 报文后会无法正确处理。

五、响应状态码

1.常用的五类状态码

  • 1××:提示信息,表示目前是协议处理的中间状态,还需要后续的操作;
  • 2××:成功,报文已经收到并被正确处理;
  • 3××:重定向,资源位置发生变动,需要客户端重新发送请求;
  • 4××:客户端错误,请求报文有误,服务器无法处理;
  • 5××:服务器错误,服务器在处理请求时内部发生了错误。

2.状态码逐个介绍

2.1 1××

1××类状态码属于提示信息,是协议处理的中间状态,实际能够用到的时候很少。

2.2 2××

2××类状态码表示服务器收到并成功处理了客户端的请求,这也是客户端最愿意看到的状态码。

  1. 200 OK 表示一切正常,通常在响应头后都会有 body 数据。
  2. 204 No Content 它的含义与“200 OK”基本相同,但响应头后没有 body 数据
  3. 206 Partial Content 状态码 206 通常还会伴随着头字段“Content-Range”,表示响应报文里 body 数据的具体范围


2.3 3××

3××类状态码表示客户端请求的资源发生了变动,客户端必须用新的 URI 重新发送请求获取资源,也就是通常所说的“重定向”,包括著名的 301、302 跳转。

  1. 301 Moved Permanently”俗称“永久重定向”,含义是此次请求的资源已经不存在了,需要改用改用新的 URI 再次访问。响应头里使用字段Location指明后续要跳转的 URI。
  2. 302 Found”,俗称“临时重定向”,意思是请求的资源还在,但需要暂时用另一个 URI 来访问。响应头里使用字段Location指明后续要跳转的 URI。
  3. 304 Not Modified” 它用于 If-Modified-Since 等条件请求表示资源未修改,用于缓存控制。它不具有通常的跳转含义,但可以理解成“重定向已到缓存的文件”(即“缓存重定向”)。

    2.4 4××

4××类状态码表示客户端发送的请求报文有误,服务器无法处理,它就是真正的“错误码”含义了。

  1. 400 Bad Request”是一个通用的错误码,表示请求报文有错误,但具体是数据格式错误、缺少请求头还是 URI 超长它没有明确说,只是一个笼统的错误。
  2. 403 Forbidden”实际上不是客户端的请求出错,而是表示服务器禁止访问资源。
  3. 404 Not Found”可能是我们最常看见也是最不愿意看到的一个状态码,它的原意是资源在本服务器上未找到,所以无法提供给客户端。
  4. 其他:
  • 405 Method Not Allowed:不允许使用某些方法操作资源,例如不允许 POST 只能 GET;
  • 406 Not Acceptable:资源无法满足客户端请求的条件,例如请求中文但只有英文;
  • 408 Request Timeout:请求超时,服务器等待了过长的时间;
  • 409 Conflict:多个请求发生了冲突,可以理解为多线程并发时的竞态;
  • 413 Request Entity Too Large:请求报文里的 body 太大;
  • 414 Request-URI Too Long:请求行里的 URI 太大;
  • 429 Too Many Requests:客户端发送了太多的请求,通常是由于服务器的限连策略;
  • 431 Request Header Fields Too Large:请求头某个字段或总体太大;

2.5 5××

5××类状态码表示客户端请求报文正确,但服务器在处理时内部发生了错误,无法返回应有的响应数据,是服务器端的“错误码”。

  1. 500 Internal Server Error”与 400 类似,也是一个通用的错误码,服务器究竟发生了什么错误我们是不知道的
  2. 501 Not Implemented”表示客户端请求的功能还不支持,这个错误码比 500 要“温和”一些,和“即将开业,敬请期待”的意思差不多,不过具体什么时候“开业”就不好说了。
  3. 502 Bad Gateway”通常是服务器作为网关或者代理时返回的错误码,表示服务器自身工作正常,访问后端服务器时发生了错误,但具体的错误原因也是不知道的。
  4. 503 Service Unavailable”表示服务器当前很忙,暂时无法响应服务,我们上网时有时候遇到的“网络服务正忙,请稍后重试”的提示信息就是状态码 503。503 响应报文里通常还会有一个“Retry-After”字段,指示客户端可以在多久以后再次尝试发送请求。


小结


  • 状态码在响应报文里表示了服务器对请求的处理结果;
  • 状态码后的原因短语是简单的文字描述,可以自定义;
  • 状态码是十进制的三位数,分为五类,从 100 到 599;
  • 2××类状态码表示成功,常用的有 200、204、206;
  • 3××类状态码表示重定向,常用的有 301、302、304;
  • 4××类状态码表示客户端错误,常用的有 400、403、404;
  • 5××类状态码表示服务器错误,常用的有 500、501、502、503。

六、HTTP特点

1.灵活可扩展

“header+body”等,报文里的各个组成部分都没有做严格的语法语义限制,可以由开发者任意定制。

2.可靠传输

因为 HTTP 协议是基于 TCP/IP 的,而 TCP 本身是一个“可靠”的传输协议,所以 HTTP 自然也就继承了这个特性,能够在请求方和应答方之间“可靠”地传输数据。

我们必须正确地理解“可靠”的含义,HTTP 并不能 100% 保证数据一定能够发送到另一端,在网络繁忙、连接质量差等恶劣的环境下,也有可能收发失败。“可靠”只是向使用者提供了一个“承诺”,会在下层用多种手段“尽量”保证数据的完整送达。

3.应用层协议

只要不太苛求性能,HTTP 几乎可以传递一切东西,满足各种需求,称得上是一个“万能”的协议。

4.请求 - 应答

这个请求 - 应答模式是 HTTP 协议最根本的通信模型,通俗来讲就是“一发一收”“有来有去”,就像是写代码时的函数调用,只要填好请求头里的字段,“调用”后就会收到答复。

5.无状态

客户端和服务器永远是处在一种“无知”的状态。建立连接前两者互不知情,每次收发的报文也都是互相独立的,没有任何的联系。收发报文也不会对客户端或服务器产生任何影响,连接后也不会要求保存任何信息。

使用cookie技术来实现有状态

6.其他特点

传输的实体数据可缓存可压缩、可分段获取数据、支持身份认证、支持国际化语言等

小结


  1. HTTP 是灵活可扩展的,可以任意添加头字段实现任意功能;
  2. HTTP 是可靠传输协议,基于 TCP/IP 协议“尽量”保证数据的送达;
  3. HTTP 是应用层协议,比 FTP、SSH 等更通用功能更多,能够传输任意数据;
  4. HTTP 使用了请求 - 应答模式,客户端主动发起请求,服务器被动回复请求;
  5. HTTP 本质上是无状态的,每个请求都是互相独立、毫无关联的,协议不要求客户端或服务器记录请求相关的信息。

七、HTTP的优点和缺点

  1. HTTP 最大的优点是简单、灵活和易于扩展;
  2. HTTP 拥有成熟的软硬件环境,应用的非常广泛,是互联网的基础设施;
  3. HTTP 是无状态的,可以轻松实现集群化,扩展性能,但有时也需要用 Cookie 技术来实现“有状态”;
  4. HTTP 是明文传输,数据完全肉眼可见,能够方便地研究分析,但也容易被窃听;
  5. HTTP 是不安全的,无法验证通信双方的身份,也不能判断报文是否被窜改;
  6. HTTP 的性能不算差,但不完全适应现在的互联网,还有很大的提升空间。