文章目录
前言
本人是一个普通程序猿!分享一点自己的见解,如果有错误的地方欢迎各位大佬莅临指导,如果你也对编程感兴趣的话,互关一下,以后互相学习,共同进步。这篇文章能够帮助到你的话,劳请大家点赞转发支持一下!
一、HTTP协议是什么
HTTP (全称为 “超文本传输协议”) 是一种应用非常广泛的应用层协议。
应用层协议
通过TCP/IP五层协议中传输层,网络层,数据链路层,物理层;我们已经了解了数据是如何在网络上进行发送接收的。而这四层实现的效果是运输数据。
应用层关注的是这些数据如何使用。
应用层协议就是用来加工处理或使用这些数据 。
应用层协议不关心通信细节,关心应用细节。
举例
假设A端要给B端发送一条信息。
A的应用层拿到这条信息, 根据应用层协议来加工处理包装成快递 ,然后向下封装交给下面四层,进行网络运输。
B的物理层收到这个快递,然后向上分用到应用层,然后B的应用层再 根据应用层协议来拆开快递 ,得到里面的信息。
HTTP协议
应用是有不同的场景的,所以应用层协议是有不同种类的,其中经典协议之一的HTTP就是其中的佼佼者。
HTTP协议是一个使用非常广泛的应用层协议 ,主要原因就是 HTTP协议的可定制性非常强 。
基本上可以说只要你上网就会用到HTTP协议,
包括微信小程序,支付宝小程序,浏览器打开一个网页,游戏的界面都会使用到HTTP协议。
HTTP协议是个 “一问一答” 形式的协议。
一问一答:
客户端向服务器发送一个请求,
服务器返回给客户端一个响应。
HTTP协议工作工程
这中间肯定传输的不是HTTP请求响应,肯定要经过层层封装再进行发送。
二、HTTP协议报文格式
咱们可以通过抓包工具来看看HTTP协议报文格式的详情。
此处使用的是Fiddler进行抓包
此处就以访问搜狗页面为例。
(一个网页的加载过程中可能会和服务器进行N次互相交互,不要以为就只交互一次!!!)
点击文本文档显示按钮,在文本文档中显示原始的完整的HTTP请求。
HTTP请求
HTTP响应
HTTP响应的正文太多,截取了部分。注意!
1️⃣HTTP请求与HTTP响应本身就是字符串。
2️⃣空行是报头的结束标记
3️⃣正文可以有也可以没有
HTTP请求
HTTP请求格式
请求行
访问搜狗页面时的请求行:
GET https://www.sogou.com/HTTP/1.1
请求行可以分为三部分:
Method(方法):GET 。
URL:https://www.sogou.com。
Version(版本号):HTTP/1.1。
Method(方法)
方法 | 说明 | 支持的HTTP协议版本 |
---|---|---|
GET | 获取资源 | 1.0、1.1 |
POST | 传输实体主体 | 1.0、1.1 |
PUT | 传输文件 | 1.0、1.1 |
HEAD | 获得报文首部 | 1.0、1.1 |
DELETE | 删除文件 | 1.0、1.1 |
OPTIONS | 询问支持的方法 | 1.1 |
TRACE | 追踪路径 | 1.1 |
CONNECT | 要求用隧道协议连接代理 | 1.1 |
LINK | 建立和资源之间的联系 | 1.0 |
UNLINE | 断开连接关系 | 1.0 |
在这些方法里,GET是最常用的,POST相对常用,其他方法都不太常用,因此本文只详细介绍GET与POST。
GET方法
GET 是最常用的 HTTP 方法,常用于获取服务器上的某个资源。
在浏览器中直接输入 URL, 此时浏览器就会发送出一个 GET 请求,另外, HTML 中的 link, img, script 等标签, 也会触发 GET 请求。
GET方法的特点:
首行的第一部分为 GET。
URL 的 query string 可以为空, 也可以不为空。
header 部分有若干个键值对结构。
body 部分一般为空。
POST方法
POST 方法也是一种常见的方法,多用于提交用户输入的数据给服务器(例如登陆页面)。
通过 HTML 中的 form 标签可以构造 POST 请求, 或者使用 JavaScript 的 ajax 也可以构造 POST 请求
POST方法的特点:
首行的第一部分为 POST。
URL 的 query string 一般为空 (也可以不为空)。
header 部分有若干个键值对结构。
body 部分一般不为空。
GET与POST的区别
GET与POST没有本质区别;
在使用GET的场景,使用POST一般来说可行。
在使用POST的场景,使用GET,一般来说也可行。
GET与POST主要是使用习惯上存在区别:
1️⃣ GET习惯用来表示 “获取一个数据” ; POST习惯用来表示 “提交一个数据” 。
2️⃣ GET一般没有body,需要携带数据则放到URL中 ; POST一般有body 。
3️⃣ GET请求通常设计成 幂等 的 ; POST无要求 。
4️⃣ GET是可缓存的(前提是幂等) ; POST不能 。
5️⃣ GET请求可以被浏览器收藏 ; POST不能 。
小贴士
虽然GET 与POST的应用场景不同,但是实际上,并非需要严格遵守HTTP中规定的应用场景,HTTP只是一种建议,在实际应用中不一定非要遵守这个规定。
这也是为什么GET的body一般为空,POST的body一般不为空,有时可能应用于非规定场景。
- 幂等:数学上的术语,大致意思就是, 输入一定,结果一定 。就比如;只要这奶是在牛身上挤的,就一定是牛奶;只要这奶是在羊身上挤得奶就一定是羊奶。所以 “挤奶” 就是幂等的。
缓存
缓存:缓存指当你这个幂等请求经服务器计算得到一次响应结果后,浏览器或服务器等设备进行缓存记录这个结果,以便下次快速返回。
浏览器缓存:浏览器可以记录(缓存)这个结果,你下次再发出这个请求,浏览器就可以直接给你结果,不用再去访问服务器。
服务器缓存:服务器记录(缓存)这个结构,其他客户端也发出同样的请求时,不用再计算了,直接返回结果。
URL
URL (Uniform Resource Locator)统一资源定位符也就是我们俗称的网址。
互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它,URL 的详细规则由因特网标准RFC1738 进行了约定。
URL格式
名称 | 说明 |
---|---|
协议方案名 | 协议方案名,常见的有http 和 https,也有其他的类型。 |
登陆信息 | 现在的网站进行身份认证一般不再通过 URL 进行了,一般都会省略。 |
服务器地址 | 此处是一个 “域名”,域名会通过 DNS 系统解析成一个具体的 IP 地址 |
端口号 | 标明服务器上对应的程序 |
带层次的文件路径 | 标记了要访问资源在服务器上的位置 |
查询字符串(query string) | 本质是一个键值对结构,键值对之间使用 & 分隔,键和值之间使用 = 分隔;作用是对访问的资源进行补充说明 |
片段标识符 | 主要用于页面内跳转 |
这是抓到的进入我CSDN个人主页的http请求包,首行的URL:
https://blog.csdn.net/The_emperoor_man?spm=1001.2014.3001.5343
可以看到省略了登录信息,端口号,片段标识符。
URL不是一成不变的,是让程序猿根据需求灵活运用的。
所以就有一部分内容可以省略。
URL可省略部分
- 协议名: 可以省略, 省略后默认为 http://
- ip 地址 / 域名: 在 HTML 中可以省略(比如 img, link, script, a 标签的 src 或者 href 属性). 省略后表示服务器的 ip / 域名与当前 HTML 所属的 ip / 域名一致。
- 端口号: 可以省略. 省略后如果是 http 协议, 端口号自动设为 80; 如果是 https 协议, 端口号自动设为 443
- 带层次的文件路径: 可以省略,省略后相当于 / ,有些服务器会在发现 / 路径的时候自动访问/index.html。
- 查询字符串: 可以省略。
- 片段标识符: 可以省略。
版本号
此处的版本号指的是HTTP的版本号。
HTTP常见版本
HTTP/1.0
HTTP/1.1(最主流版本)
HTTP/2
HTTP/3
请求报头(header)
依旧拿抓到的我CSDN个人主页的包来讲解。
header 的整体的格式也是"键值对" 结构 ; 每个键值对占一行,键和值之间使用 " : " 分割 ;键值对可以有N行,不作限制,以空行作为结束标记 。
header中的键值对大部分都是HTTP协议规定的,也可以添加自定义的键值对。
Host
Host属性表示服务器主机的地址和端口号。
URL中也有地址与端口号,这俩货有啥区别呢?。
Host与URL中地址与端口号的区别
假设A端通过代理K端与B端进行交互。
此时A与B进行交互的信息,都要先交给K端,K端再进行转发。
那么此时:
A或B端的HTTP请求中的请求报头中的 Host始终记录的是对方即最终目的地 。
A或B端的HTTP请求中的请求行中的 URL的地址与端口号要记住的是当前目的地 。
举例
A要给B发送一个HTTP请求;发送过程:A要先发送给K,K再发送给B。
A端构造的HTTP请求中 Host存储的是B端(最终目的地) 的信息, URL中存储的则是K端(当前目的地) 的信息。
当然如果没有代理转发的话,他俩存储的就是相同的地址端口号。
Content-Length与Content-Type
Content-Length属性表示 请求正文(body) 中数据的长度(单位:字节)。
Content-Type属性表示 请求正文(body) 中的数据格式。
所以如果这个HTTP请求中没有body部分,那么这两个属性就会省略。
我个人主页的包就没有body,因此请求报头中也没有Content-Length这个属性。
一般POST都会有body,登录时一般发送的都是POST。下面就抓了一个登录时发送的包截取了这两个属性的部分,来看一下。
Content-Type有很多种:
作为HTTP请求时
常见的有两种:
application/json;
表示body 数据格式是json格式。
application/x-www-form-urlencoded
表示body 数据格式是form表单提交的数据格式
作为HTTP响应时
常见的有许多种:
text/html
表示body 数据格式是 HTML
text/css
表示body 数据格式是 CSS
application/javascript
表示body 数据格式是 JavaScript
application/json
表示body 数据格式是 JSON
还有image/jpg等等…
User-Agent
User-Agent主要表示浏览器/操作系统的属性
Referer
Referer表示这个页面是从哪个页面跳转过来的。
这是我在搜狗中点击百度链接时,抓取的百度的包,此时的Referer显示的就是搜狗的网址,因为我是从搜狗页面跳转过来的。
注意!!
如果直接在浏览器中输入URL, 或者直接通过收藏夹访问页面时是没有 Referer 的
Cookie
Cookie是浏览器在本地存储用户自定义数据的关键机制。Cookie中存储了一个字符串,实现身份标识的功能。
Cookie中只能存储字符串!!!
- Cookie的值也是键值对,键值对之间用 ; 分割,键和值之间用 = 分割。
Cookie的本质是浏览器在本地存储用户自定义数据的关键机制。
虽然说各种数据都是在服务器中存储的,但是浏览器也要存储一些数据比如用户身份信息。
就比如逛淘宝,你点击去一个商品详情页就要输入一次信息,那多麻烦啊!如果浏览器存储了用户的身份信息,就不用频繁输入信息了。
那么存储到哪里呢?为了用户安全,网页是禁止直接访问硬盘的。
因此 浏览器提供了Cookie机制,允许网页往浏览器中存储一些自定义的键值对,浏览器存储的这些键值对,通过浏览器提供的api写入特定的文件。
网站很多,每个网站都存Cookie, Cookie是按照域名为维度进行存储的 。
同一家网站(百度搜索,百度图片…)共享同一份Cookie 。
不同家的网站有各自不同的Cookie 。
Cookie从哪来
这个数据可能是客户端(网页)自行通过 JS 写入的, 也可能来自于服务器(服务器在 HTTP 响应的 header 中通过 Set-Cookie 字段给浏览器返回数据)。
此处展示 Set-Cookie来源 。
拿gitee举例:
先删除存有的Cookie。
重新登录进行抓包
浏览器访问服务器,服务器通过HTTP响应中的Set-Cookie将Cookie键值对返回给浏览器。
可以看到, 响应中包含了 3 个 Set-Cookie 属性
第三个Set-Cookie(绿色方框)里面包含了一个 gitee-session-n 这样的属性, 属性值是一串很长的加密之后的信息. 这个信息就是用户当前登陆的身份标识. 也称为 “令牌(token)”。
Cookie往哪去
在下次发出HTTP请求的时候把Cookie带给服务器。
再次访问gitee网站就会携带保存的Cookie。
Cookie有啥用
Cookie保存一些信息(身份信息等),你下次再访问对应的服务器时,就不用再填写这些信息,而可以直接被服务器识别。
HTTP响应
HTTP响应格式
HTTP响应与HTTP请求唯二的区别就是状态码与状态码描述 ,除这两个属性有差异外,其他属性都相同。
状态码(status code)与状态码描述
状态码就是数字 ,用来 表示访问一个页面的结果 (是访问成功, 还是失败, 还是其他的一些情况…)。
状态码描述 通过一个或一组单词来描述状态码的含义 。
举例
404 NOT Found
这个组合表示要访问的资源不存在。
原因:浏览器输入一个 URL,目的就是为了访问对方服务器上的一个资源,如果这个 URL 标识的资源在服务器上不存在,那么就会出现 404 NOT
Found。
200 OK
这个组合表示成功访问服务器。
500 Internal Server Error
这个组合表示服务器出现内部错误。
原因:服务器的代码执行过程中遇到了一些特殊情况(服务器异常崩溃)会产生这个状态码与状态码描述。
详情见:HTTP响应状态码大全
HTTP中提供的状态码非常繁多,一共可以分为五大类。
状态码 | 类别 | 原因短语 |
---|---|---|
1XX | Informational(信息性状态码) | 接收的请求正在处理 |
2XX | Success(成功状态码) | 请求正常处理完毕 |
3XX | Redirection(重定向状态码) | 需要进行附加操作以完成请求 |
4XX | Client Error(客户端错误状态码) | 服务器无法处理请求(请求不合法) |
5XX | Server Error(服务器错误状态码) | 服务器处理请求出错(服务器出BUG) |
总结
以上就是要分享的HTTP协议的所有内容了,本文详细介绍了HTTP协议的报文格式,并通过抓包来详细展示了目前真实使用中的HTTP请求与响应,越来越靠近真正的编程了,激动!!
路漫漫不止修身,也养性。