文章目录

  • HTTP 协议报文
  • 如何查看 HTTP 协议报文
  • HTTP 协议请求报文解读
  • 首行
  • URL
  • 方法
  • 经典面试题: GET 和 POST 之间的典型区别
  • body
  • HTTP 协议响应报文解读
  • 首行
  • HTTP 状态码 和 状态码描述
  • 总结


HTTP 协议属于是应用层协议中, 使用最广泛的协议之一

浏览器获取到网页, 就是基于 HTTP 协议来实现的

总的来说, HTTP 协议就是浏览器和服务器之间的桥梁

HTTP 协议报文

如何查看 HTTP 协议报文

想要查看 HTTP 协议的交互详细过程, 我们可以通过第三方工具来查看, 这第三方工具, 在这里简称 “抓包” 工具, 这里我会使用 fiddler 来抓取 HTTP 包

在这里, 我先打开 fiddler, 再打开搜狗的主页

requests 查看发送的报文_网络

接着查看 fiddler 里面抓取的信息

requests 查看发送的报文_requests 查看发送的报文_02

双击打开, 再点击右边的 RAW, 接着点 View in Notepad.

requests 查看发送的报文_HTTP_03

于是我们就能在记事本中查看到抓取搜狗主页的 HTTP 请求的协议报文了

requests 查看发送的报文_服务器_04

接着来看右下角, 是搜狗服务器发的响应报文

requests 查看发送的报文_HTTP_05

点开查看, 发现里面好多都是乱码

requests 查看发送的报文_requests 查看发送的报文_06

其实响应的数据原本也是文本, 但是有的浏览器会对响应进行压缩操作(将文本变为二进制了), 这样做的目的其实就是为了节省带宽, 想要看到原始的文本数据, 就可以点击 fiddler 上的这个按钮来用文本来进行显示

requests 查看发送的报文_HTTP_07

这样就能得到文本形式的 HTTP 协议相应的报文

requests 查看发送的报文_服务器_08

HTTP 协议请求报文解读

首行

requests 查看发送的报文_服务器_09

打开刚才抓包的数据包, 可以看到第一行的内容, 被空格分为了三个部分, 其中,

  • GET : 是 HTTP 的方法(method)
  • http://sogou.com/ : URL
  • HTTP/1.1 : 版本号
URL

requests 查看发送的报文_http_10


上面图片表示的是一个经典的 URL 实例

虽然看过去很复杂, 但是在 URL 中最关键的有四个部分

  1. 域名 / IP
  2. 端口号
  3. 带层次的路径
  4. 查询字符串

注意, 一个 URL里面的几个部分, 有些是可以省略的, 就比如 https://sogou.com/ 中, 就省略了端口号
省略端口号的时候, 浏览器会提供一个默认的端口, 对于 http 来说, 默认端口是 80, 对于 https 来说, 默认端口是 443

在这里举个栗子来理解一下 URL
假如我还是去某个大学的餐厅卖北京烤鸭, 其中有这样一份订单(这里用 URL 来形象化)

XX大学一餐厅:9号窗口/北京烤鸭?甜面酱=要&葱段=要&黄瓜丝=不要

在上面的一个 URL 中

  • XX大学一餐厅: IP地址
  • 9号窗口: 端口号
  • 北京烤鸭: 带层次的路径
  • 甜面酱=要&葱段=要&黄瓜丝=不要: 查询字符串(使用键值对的形式来组织)

如果没有给出查询字符串, 那么就按照默认的来做

方法

requests 查看发送的报文_服务器_11

方法描述这次请求的语义, 就是这次请求想干啥, 最常用的是 GET 和 POST 方法.

产生 GET 请求的方式:

  1. 在浏览器地址栏里直接输入 URL
  2. HTML 中的 link, script, img, a 标签等
  3. 通过 JS 来构造 GET…

requests 查看发送的报文_http_12


上面就是一个经典的 GET 请求包, 可以看到 GET 请求是通过首行和 header 来构造的.


requests 查看发送的报文_网络_13


这是一个 POST 请求, 其中不同于 GET 请求, POST 请求多了一个 body(正文), 其中 body 里面的数据, 全部都是程序员自定义的内容.

经典面试题: GET 和 POST 之间的典型区别

GET 和 POST 之间其实是没有本质上的区别的, 在大部分的场景下, 它们之间都能够相互替代.

但是在使用习惯上, 还是有差别的

  1. GET 也可以向服务器传递信息, GET 传递信息一般都是放在 query string 中, 而 POST 传递信息一般都是放在 body 中. 但是这只是一种习惯上的用法, GET 请求也可以有 body, POST 请求也可以有query string, 有和没有都要看程序员自己的实现, 但是一般情况下非常的少见.
  2. 它们两个有语义上的差别, GET 请求一般是用于从服务器获取数据的, 而 POST 请求一般是给服务器提交数据的… 但是完全也可以使用 GET 提交, POST 获取.
  3. GET 请求一般设置为幂等(相同的输入, 返回的结果也是相同的)的, POST 请求不要求幂等… 但是也完全可以 POST 设置成幂等的, GET 不设置成幂等的.
  4. GET 可以被缓存, 而 POST 一般不能被缓存, 其本意是把请求的结果保存下来, 下次请求就不必给服务器真的发送请求了, 直接去缓存里面拿结果就可以了.
body
  • Host
    Host 中大概描述了服务器所在的 地址 和 端口, 这里的地址和端口用来描述最终要访问的目标, 而这个内容大概率和 URL 中是一样的, 但是也有一定的情况下是不同的.
  • Content-Length 和 Content-Type
    Content-Length 表示 body 中的数据长度
    Content-Type 表示请求的 body 中的数据长度
    注意: 如果是 GET 请求, 没有 body, 请求中没有这两个字段, 如果是 POST 请求, 有 body, 则必须要有这两个字段
  • User-Agent(UA)
    描述了用户浏览器和操作系统的版本, 现在的 UA 主要用来区分 PC 和 移动端
  • Referer
    描述了当前页面的来源(如果是直接点击收藏夹进的网页, 或者是直接通过地址栏中输入地址访问的网页, 是没有 Referer 的). Referer 现在主要是用来统计用户点击广告的来源的(比如是通过哪个搜索引擎点的广告, 广告商会根据这个来计费)
  • Cookie
    Cookie 是非常重要的 header 属性, 本质上是浏览器给网页提供的本地存储数据的机制. 在网页中, 默认是不允许访问计算机的硬盘的(以保证安全). Cookie 也是对于访问硬盘做出了明确的限制, 里面的数据是程序员自定义的, 通过键值对的方式来组织的.
  1. Cookie 是在哪存的?
    Cookie 中的数据是来自于服务器中的, 服务器会通过 HTTP 响应的报头部分中的 Set-Cookie 字段, 来决定浏览器的Cookie 要存什么.
  2. Cookie 是在哪存的?
    可以认为 Cookie 是存在于浏览器中的, 存在于硬盘的.
    Cookie 在存的时候, 是按照浏览器 + 域名 的维度来进行细分的. 在不同的浏览器中, 各自存各自的 Cookie, 在同一个浏览器中, 不同的域名对应的 Cookie 也是不同的.
    Cookie 中不止存键值对, 还存了 过期时间.
    有很多网站登陆一次后, 会自动记录登录状态.
  3. Cookie 要到哪里去?
    Cookie 最终会回到服务器中. 访问服务器的客户端, 在同一时刻是有很多的, 客户端这边就是通过 Cookie 来保存用户使用的中间状态, 当客户端访问服务器的时候, 会自动的把 Cookie 的内容带入到请求中, 服务器就能通过这个 Cookie 来判断客户端现在是什么状态的.

HTTP 协议响应报文解读

requests 查看发送的报文_服务器_14


上图是一个响应的报文, 分为四个部分

  1. 首行
  2. header
  3. 空行
  4. body(正文)
首行

首行中, 有三个值, 用空格隔开. 分别是 版本号 状态码 状态码描述

HTTP 状态码 和 状态码描述

requests 查看发送的报文_网络_15


状态码描述的是这次响应的结果, 是成功了 / 失败了, 以及失败的原因是什么

这边介绍几个常见的状态码和描述

状态码

英文名称

中文描述

200

OK

请求成功 一般用于GET与POST请求

403

Forbidden

服务器理解请求客户端的请求,但是拒绝执行此请求(没有权限)

404

Not Found

服务器无法根据客户端的请求找到资源(网页)

302

Found

临时移动 资源临时被移动 客户端应继续使用原有URI(重定向)

500

Internal Server Error

服务器内部错误,无法完成请求

504

Gateway Time-out

充当网关或代理的服务器,未及时从远端服务器获取请求

总结

到这就是基本的 HTTP 的报文解读了, 其中重要的就是请求报文和响应报文, 下图是整体的 HTTP 交互结构

requests 查看发送的报文_网络_16