目录
初识HTTP
什么是HTTP
HTTP (全称为 "超⽂本传输协议") 是⼀种应⽤⾮常⼴泛的 应⽤层协议.
为什么是超文本
文本=>字符串
所谓 "超⽂本" 的含义, 就是传输的内容不仅仅是⽂本(⽐如 html, css 这个就是⽂本), 还可以是⼀些其他的资源, ⽐如图⽚, 视频, ⾳频等⼆进制的数据
版本
最新的 HTTP 3 版本也正在完善中, ⽬前 Google / Facebook 等公司的产品已经⽀持了.
HTTP 往往是基于传输层的 TCP 协议实现的. (HTTP1.0, HTTP1.1, HTTP2.0 均为TCP, HTTP3 基于 UDP 实现)
⽬前我们主要使⽤的还是 HTTP1.1 和 HTTP2.0 . 目前互联网上见到的HTTP协议,绝大部分都是HTTP1.1版本
HTTPS
HTTPS可以认为是HTTP的升级版,和HTTP的区别就在于引入了一个"加密层"(HTTPS的安全性更高一些),除了安全性之外,HTTPS和HTTP完全一样的了
模型
HTTP协议,是一种典型的"一问一答模型”的协议
客户端->服务器
客户端发一个请求,服务器返回一个响应(一一对应)
打开网页这种场景,就属于典型的一问一答的模式
非“一一对应”模型
一问多答 下载一个大的文件
多问一答 上传一个大的文件
多问多答 远程桌面(远程控制)
HTTP抓包工具
为什么使用
抓包工具相当于⼀个 "代理",借助抓包工具,观察到HTTP请求/响应的详细情况
浏览器访问 sogou.com 时, 就会把 HTTP 请求先发给抓包工具, 抓包工具再把请求转发给 sogou 的服务器. 当 sogou 服务器返回数据时, 抓包工具 拿到返回数据, 再把数据交给浏览器.
因此 抓包工具 对于浏览器和 sogou 服务器之间交互的数据细节, 都是⾮常清楚的.
代理就可以简单理解为⼀个跑腿⼩弟. 你想买罐冰阔落, ⼜不想⾃⼰下楼去超市, 那么就可以把钱给你的跑腿⼩弟, 跑腿⼩弟来到超市把钱给超市⽼板, 再把冰阔落拿回来交到你⼿上. 这个过程中, 这个跑腿⼩弟对于 "你" 和 "超市⽼板" 之间的交易细节, 是⾮常清楚的.
抓包工具的下载
下载后的重要操作
由于当前网络上大部分网站都是HTTPS,需要开启Fiddler的HTTPS功能.
只要启动Fiddler,此时,抓包工作就自动开始了,这里虽然不进行任何操作,Fiddler也能抓到很多包,这是正常的,你的电脑上有些软件,可能就在不停的在后台偷偷的和服务器进行交互
Fiddler的使用
可以使⽤ ctrl + a 全选左侧的抓包结果, delete 键先清除所有被选中的结果,再刷新搜狗页面
点击某一项,右侧就能看到请求和响应的详细情况
右侧上⽅显⽰了 HTTP 请求的报⽂内容.
右侧下⽅显⽰了 HTTP 响应的报⽂内容.
切换到 Raw 标签⻚可以看到详细的数据格式
Raw标签页就是HTTP的原始数据
发送HTTP请求,就是往TCP socket中,按照上述格式,写入一段字符串.
收到HTTP响应,就是从TCP socket中,读出一段字符串再解析
请求和响应的详细数据, 可以通过右下⻆的 View in Notepad 通过记事本打开.
响应这里用记事本打开后,看到的是二进制,因为出现乱码了(其实本身响应也是文本,此处的二进制,是压缩后的)。为什么要压缩呢?在二进制的角度上对数据进行重新编码,体积小了,传输时消耗的带宽就低了,保证信息量不变,体积缩小。带宽可是互联网中最贵的硬件资源比CPU,内存都贵。那怎么才能不看到乱码?
点这里进行解压缩,再用记事本打开
搜狗主页中,返回的响应数据,解压缩之后,其实就是主页的HTML.很多网站也是如此,浏览器看到的网页就是由HTML,CSS,JavaScript构成。返回一个HTML给浏览器就是HTTP非常典型的场景。
HTTP请求与响应的基本格式
HTTP请求基本格式

首行:
[⽅法](HTTP请求的方法(method),这次请求的"动作"是啥)+[url](访问的资源是啥) +[版本]
请求头Header:
请求的属性, 冒号分割的键值对;每组属性之间使⽤\n分隔;从第二行开始的若干行,一直到空行结束
HTTP中,请求头里的键值对都有哪些,是HTTP标准规定的.不同的请求头,都有特定的含义,但是标准也允许用户自定义一些请求头
空行:
正文Body:
空⾏后⾯的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有⼀个Content-Length属性来标识Body的⻓度;我们上面的例子是没有这部分内容的
HTTP响应基本格式
首行:
[版本号] + [状态码] + [状态码解释] 200是最常见的一个状态码,表示成功
Header:
请求的属性, 冒号分割的键值对;每组属性之间使⽤\n分隔;遇到空⾏表⽰Header部分结束
键值对也是标准规定的,有的键值对,只能出现在请求中,有的只能出现在响应中,有的呢都能出现
空行:
Body:
空行后⾯的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有⼀个Content-Length属性来标识Body的⻓度; 如果服务器返回了⼀个html页面, 那么html页面内容就是在body中.
协议格式总结❗️❗️❗️

为什么 HTTP 报⽂中要存在 "空行"?
因为 HTTP 协议并没有规定报头部分的键值对有多少个. 空⾏就相当于是 "报头的结束标记", 或者是 "报头和正⽂之间的分隔符".
HTTP 在传输层依赖 TCP 协议, TCP 是⾯向字节流的. 如果没有这个空⾏, 就会出现 "粘包问题".
HTTP 详解
认识 URL
平时我们俗称的 "⽹址" 其实就是说的 URL (Uniform Resource Locator 统⼀资源定位符).
网络上资源那么多(资源可以是一个网页,可以是一个文件,可以是一个图片…),必须要有一套规则,能够找到某个指定的资源。
URL基本格式
关于 URL encode
像 / ? : 等这样的字符, 已经被url当做特殊意义理解了. 因此这些字符不能随意出现.
⽐如, 某个参数中需要带有这些特殊字符, 就必须先对特殊字符进⾏转义.
⼀个中⽂字符由 UTF-8 或者 GBK 这样的编码⽅式构成, 虽然在 URL 中没有特殊含义, 但是仍然需要进⾏转义. 否则浏览器可能把 UTF-8/GBK 编码中的某个字节当做 URL 中的特殊符号.
转义的规则如下: 将需要转码的字符转为16进制,然后从右到左,取4位(不⾜4位直接处理),每2位做⼀位,前⾯加上%,编码成%XY格式
日常开发的时候,大多数情况不需要手动处理转码的,日常使用的一些库(无论是前端的还是后端的,一般都是自带了url encode/decode的功能的)。
HTTP的方法
GET 方法
使用场景
GET 是最常⽤的 HTTP ⽅法. 常⽤于获取服务器上的某个资源.
1️⃣在浏览器中直接输⼊ URL, 此时浏览器就会发送出⼀个 GET 请求.
2️⃣另外, HTML 中的 link, img, script 等标签, 也会触发 GET 请求.
3️⃣后⾯我们还会学习, 使⽤ JavaScript 中的 ajax 也能构造 GET 请求.
最上⾯的
是通过浏览器地址栏发送的 GET 请求
下⾯的和 sogou 域名相关的请求, 有些是通过 html 中的 link/script/img 标签产⽣的, 例如
有些是通过 ajax 的⽅式产⽣的, 例如
POST 方法
使用场景
1️⃣登录/注册
2️⃣上传文件
除此之外,POST也有很多其他的场景。其实,HTTP中的GET和POST很多时候都是可以通用的
📝面经:GET和POST的区别
🍂语义不同:GET一般用于获取数据,POST一般用于提交数据!
🍂传递数据的方式不同:GET的body一般为空,需要传递的数据通过query string传递,POST的query string一般为空,需要传递的数据通过body传递
🍂GET请求一般是幂等的,POST请求一般是不幂等的.(如果多次请求得到的结果一样,就视为请求是幂等的)
🍂GET可以被缓存,POST不能被缓存.(这一点也是承接幂等性).
认识 "报头" (header)
header 的整体的格式也是 "键值对" 结构. 每个键值对占⼀⾏. 键和值之间使⽤分号分割.
报头的种类有很多, 此处仅介绍⼏个常⻅的.
Host
表⽰服务器主机的地址和端⼝,这部分信息,其实在URL已经有所体现了
Content-Length
表⽰ body 中的数据⻓度.
Content-Type
表示请求的 body 中的数据格式.浏览器会根据这里的值决定如何解析body的内容
application/json: 数据为 json 格式. body 格式形如:
{"username":"123456789","password":"xxxx","code":"jw7l","uuid":"d110a05ccde64b16}
后续自己编写后端代码的时候也需要手动设置Content-Type让响应能够被正确解析,Content-Type和Content-Length都属于是在请求和响应中都会存在的,一个请求/响应中,没有body,也就没有这俩字段,如果有body,则必须要有这俩字段。
User-Agent (简称 UA)
表示浏览器/操作系统的属性.
形如:
判定UA字段,通过UA获取到用户的浏览器信息和操作系统信息,可以判定当前用户的浏览器版本都支持哪些特性,是只支持文字图片,还是说能支持多媒体。在今天,浏览器大家都差不多,比如放到7,8年前,需要考虑兼容1E浏览器,开发人员还是要头疼一些的。现在虽然浏览器功能差不多,但是上网的设备,还是存在差别,手机和电脑的屏幕尺寸比例是截然不同的,仍然可以通过UA这样的方式来切入。
针对上述问题,在前端开发圈子里,研究出了个东西"响应式编程",在前端代码中(主要是CSS),能够自动查询出当前屏幕的尺寸,结合尺寸对页面自动进行重新排版。
UA现在还有一个作用,就是用来做数据统计。是日常开发的重要环节,统计很多的业务指标,根据统计结果,进一步的迭代改进产品。UA的统计主要就是用来区分PC和移动端。
Referer
描述了当前页面,是从哪个页面跳转过来的,Referer并不一定真的有,如果直接在浏览器中输⼊URL,或者直接通过收藏夹访问⻚⾯时是没有 Referer 的。
同一个广告主,会在多个平台多个渠道投放广告,在百度上点击,会跳到广告主的网站,在搜狗上点击,也会跳到广告主的网站,广告主在自己的网站这边,是可以很容易的统计出一段时间内有多少访问量的(有多少广告点击的)。如何区分,哪些点击是来自于百度,哪些来自于搜狗呢?Referer就可以用来区分的。
Cookie

Cookie是什么?Cookie是浏览器本地持久化存储数据的一种机制,按照键值对方式存储,键值对的内容都是程序员自定义的,按照域名为维度分别进行存储。每个网站有自己的Cookie,相互不影响。
Cookie从哪里来?服务器返回的响应数据中,包含Set-Cookie字段,服务器这边的程序员根据需要,编写代码生成的。
Cookie到哪里去?后续浏览器访问同一个服务器的时候,就会把之前存储的Cookie再带上,从而发送到服务器这边。
Cookie上面存的键值对,都是程序员根据需要自定义的,其中有一个场景,Cookie非常经典的使用场景。使用Cookie保存用户的身份信息。对于HTTP来说,针对同一个服务器,每次HTTP请求,彼此,之前都是独立的,登录是前一个请求,后续的请求是如何知道我处于登录状态呢?
随着互联网技术的发展,cookie也不是唯一一个在浏览器这边存储数据的机制了
HTTP 响应状态码
认识 "状态码" (status code)
200 OK
这是⼀个最常⻅的状态码,表⽰访问成功。抓包抓到的⼤部分结果都是 200。
404 Not Found
没有找到资源.
浏览器输⼊⼀个 URL, ⽬的就是为了访问对⽅服务器上的⼀个资源. 如果这个 URL 标识的资源不存在, 那么就会出现 404
例如, 在浏览器中输⼊ www.sogou.com/index.html , 此时就在尝试访问 sogou 上的 /index.html 这个资源.如果输⼊正确, 则可以正确访问到. 但是如果输⼊错误, ⽐如 www.sogou.com/index2.html , 就会看到 404 这样的响应.
403 Forbidden
表⽰访问被拒绝. 有的⻚⾯通常需要⽤⼾具有⼀定的权限才能访问(登陆后才能访问). 如果⽤⼾没有登陆直接访问, 就容易⻅到 403.
例如: 查看码云的私有仓库, 如果不登陆, 就会出现 403.
405 Method Not Allowed
前⾯我们已经学习了 HTTP 中所⽀持的⽅法, 有 GET, POST, PUT, DELETE 等.
但是对⽅的服务器不⼀定都⽀持所有的⽅法(或者不允许⽤⼾使⽤⼀些其他的⽅法).
500 Internal Server Error
服务器出现内部错误. ⼀般是服务器的代码执⾏过程中遇到了⼀些特殊情况(服务器异常崩溃)会产⽣这个状态码.
咱们平时常⽤的⽹站很少会出现 500 (但是偶尔也能看到).
504 Gateway Timeout
当服务器负载⽐较⼤的时候, 服务器处理单条请求的时候消耗的时间就会很⻓, 就可能会导致出现超时的情况.
这种情况在双⼗⼀等 "秒杀" 场景中容易出现, 平时不太容易⻅到.
302 Move temporarily
临时重定向.
理解 "重定向"
就相当于⼿机号码中的 "呼叫转移" 功能.
⽐如我本来的⼿机号是 186-1234-5678, 后来换了个新号码 135-1234-5678, 那么不需要让我的朋友知道新号码,
只要我去办理⼀个呼叫转移业务, 其他⼈拨打 186-1234-5678 , 就会⾃动转移到 135-1234-5678 上.
在登陆⻚⾯中经常会⻅到 302. ⽤于实现登陆成功后⾃动跳转到主⻚.
响应报⽂的 header 部分会包含⼀个 Location 字段, 表⽰要跳转到哪个⻚⾯.