详解 HTTP 协议

简介: 详解 HTTP 协议

引言



1. 什么是 HTTP


HTTP:Hyper Text Transfer Protocol(超文本传输协议)


(1) 超文本


看到超文本,就可以联想到 HTML

HTML:Hypertext Markup Language ( 超文本标记语言 )


在早期的时候,HTTP 被设计出来就是为了下载 HTML,而超文本的含义,顾名思义,它并不像早期的报纸一样,只有文字和图片的排版,它更有视频、音频、链接、动态效果…等这些特殊的信息。


超文本是用超链接的方法,将各种不同空间的文字信息组织在一起的网状文本。(来源于:百度百科)


按我个人的理解,超文本使得当代较于信息初代而言,就是让信息变得更加花里胡哨了,让信息换了不同的形式呈现在了计算机用户的面前。


(2) 传输


传输主要指的是两台计算机进行信息的交互,靠什么交互?肯定就是网络了。

客户端与服务器这样的传输模型最为常见,一般来说,客户端需要先发送请求,服务器之后再返回响应。


(3) 协议


协议就是一种约定,前面的博客有提到,不再赘述。


2. 理解 HTTP


(1) HTTP 协议属于应用层


8252cff2d07d4f75870e9d5acd6056d0.png


可以看到,HTTP 协议属于应用层,应用层也是 开发人员 / 程序员 与其打交道最多的一层,这一层与 Web 开发紧密相连。


(2) HTTP 协议是一发一收的模型


此外,在网络通信中,基本上都是客户端与服务器之间的联系。它们之间的沟通一般分为:一发一收、多发一收、一发多收、多发多收。


而 HTTP 协议就是一发一收的这种模型,当然,这也是最常见的一种模型。


50d9943577274c31979810749a5e35ac.png


(3) HTTP 协议是文本格式的协议


HTTP 协议是一种文本格式的协议,所以不能直接传输二进制数据,如果是图片、视频、音频…等,需要对这些数据进行特殊编码,再进行传输。


一、理解 URL



URL:Uniform Resource Locator ( 统一资源定位器 )


URL 其实就是,俗称的 " 网址 "。互联网上的每个文件都有一个唯一的URL,它是因特网的万维网服务程序上用于指定信息位置的表示方法。URL 的详细规则由因特网标准RFC1738 进行了约定。


1. URL格式


c27ddcb834f84f9aa3d1e241131741f1.png


① 协议方案名:URL支持很多种协议,例如:http, https, ftp, file…


② 登录信息(认证):现在基本已经废弃了登录信息格式;现代的做法就是:进入网页后,要求另外输入用户名和密码。


服务器地址:这里不带 /。服务器地址既可以是域名,也可以是 IP 地址。


例如:www.sogou.com ( 这是一个域名,但域名本质上就是一个 IP 地址,写域名的本质只是为了方便普通用户使用,所以域名并不是硬性条件。 )


服务器端口号:可写可不写,如果不写端口号,浏览器就会给一个默认端口号,http 默认值 80,https 默认值 443.


带层次的文件路径:表示访问服务器上不同的资源,例如:HTML,CSS,JS…


查询字符串:( query string ),查询字符串表示,浏览器给服务器传递的一些参数,开发人员可以自定义参数的内容。这些参数基本都是以键值对的方式来组织的。


查询字符串以 ? 作为起始标志。


键值对之间,用 & 分割,键和值之间,使用 = 分割

而每个键值对是什么意思,这是根据开发人员自定义来的,所以不同网页、不同公司,很大可能,键值对含义不同。


片段标识符:不常用,通常用来定位到一个 HTML 页面中的某个具体位置。


注意

上面七个组成 URL 的要素,其实每一个都可以省略,这需要根据不同的场景来进行设定。


例如:

https://www.sogou.com/


这是我们平时登录的搜狗网站,可以看到:URL 只由协议名 https 和 域名组成,其他皆省略,那么默认端口号就是 443,路径就是 / ,表示根路径。而其他的几个元素,本来就是可有可无的。


2. URL encode


在上面的 URL 格式中,我们理解了:像【 / ? : 】等这样的字符,已经被 URL 当做特殊意义理解了,因此这些字符不能随意出现。那么,某个参数中需要带有这些特殊字符,就必须先对特殊字符进行转义。这就和 Java 中的转义字符是一个道理,但是这里的转义方式却大不相同。


特殊字符 > 转义字符:  URL encode
转义字符 > 原字符:    URL decode


例如:我们使用搜狗搜索【 ?+ 】这类字符的时候,就会转义成下面的形式,当然,中文也会被转义。字符遵循 ASCII 码的十六进制转换;中文遵循 UTF-8 编码转换。


e895407868664b72b3cfb32124288966.png


注意


虽然浏览器会自动对这里的特殊符号进行 encode,但有的时候,我们需要自己手动构造的 URL,浏览器不一定支持自动的 encode。所以为了稳妥起见,我们自己构造URL中,若带有特殊符号, 一定要手动的 encode,否则就可能请求发送失败。


试想:广大电脑的使用者就是客户端,当用户上网查资料的时候,如果给服务器发送请求,但是因为特殊字符的原因,导致请求失败,那么服务器自然就无法响应,长此以往,这必然是一个重大缺陷。可能的一个原因就是:用户与用户之间使用的浏览器不同,有些非主流的浏览器并不能很好地兼容特殊字符…


例如:在前端的 HTML 中,有一个 a 标签:


095e20453eac4df9aae1a79bd48c8240.png


二、HTTP 请求



HTTP 请求的基本格式


以下面图片为例:


6845d109303747a29f94af02f6ef9d63.png


HTTP 请求的基本格式一般分为四个部分:


① 首行


HTTP 请求的首行十分有特点:


【请求方法】+ 空格 +【URL】+ 空格 +【版本号】


② header 请求头:每一行都是一个键值对。


③ 空行


④ 正文 body


1. GET 方法


GET 是最常用的 HTTP 方法,常用于获取服务器上的某个资源。


哪些情况可以构造出 HTTP GET 请求呢?


① 在浏览器中直接输入 URL

② 另外,HTML 中的 link, img, script 等标签,也会触发 GET 请求。

③ 后面我们还会学习,使用 JavaScript 中的 ajax,也能构造 GET 请求。

④ form 表单

⑤ 使用 Java 代码 / 其他库

⑥ 通过 linux 下的 wget / curl

⑦ 通过第三方工具,postman 这类工具。


展示


我们在 chrome 浏览器中直接输入 URL,以搜狗首页为例,再通过抓包后,为我们呈现的请求。观察 GET 方法:


9137ee5556324888a1009c1e98e19b2b.png


① 首行的第一部分为 GET.


② GET 后面跟了一个空格,空格后跟了当前的 URL,当前的 URL 的 【query string 】为空,这是因为我们并没有通过搜狗搜索信息。当我们搜索信息的时候,当然就不为空了。


③ header 部分有若干个键值对结构。


④ 一般给服务器发送请求情况下,GET 对应的 body 部分都为空。但也可以自己构造一个 body 不为空的请求,这需要根据不同的场景,然而,这种 body 不为空的场景较为少见。


注意


关于 GET 请求的 URL 长度问题:


HTTP 协议由 RFC 2616 标准定义,标准原文中明确说明: " Hypertext Transfer Protocol – HTTP/1.1," does not specify any requirement for URL length.

即没有对 URL 的长度有任何的限制。


然而,实际 URL 的长度取决于浏览器的实现和 HTTP 服务器端的实现。不同的浏览器设定的 URL 最大长度可能是不同的,但当代主流浏览器支持的 URL 最大长度一般都很长。


2. POST 方法


POST 方法也是一种常见的方法。多用于提交用户输入的数据给服务器 ( 例如登陆页面 )。POST 方法可以通过 HTML 中的 form 标签构造 POST 请求,也可以使用 JavaScript 的 ajax 也构造 POST 请求。


展示


我们在 chrome 浏览器中登录 QQ 邮箱,再通过 fiddler 抓包后,为我们呈现的请求。观察 POST 方法:


f4095c53e3014013afd948d6f0c5f122.png


① 首行的第一部分为 POST.


② POST 后面跟了一个空格,空格后跟了当前的 URL。当前的 URL 的 【query string 】为空。因为 POST 的 【query string 】一般就为空,当然,开发人员也可以设计不为空。


③ header 部分有若干个键值对结构。


④ 一般给服务器发送请求情况下,POST 对应的 body 部分不为空。当然,这并不是绝对的。因为 body 中的内容是根据开发人员自己设定的,换句话说,其中的代码逻辑,只有开发人员知道。


3. GET 和 POST 的区别( 经典面试题 )


答:


HTTP 协议中的各个方法之间,尤其是 GET 和 POST ,这两者并没有本质的区别。但依然存在细微的差别,然而这些细微的差别可有可无,根据自定义情况设定。


细节上的差别,例如:


① 数据位置:一般来说,GET 请求习惯将自定义数据放到 【query string】, POST 请求则是把自定义数据放入 正文body.


② 语义区别:一般来说,GET 请求用于 获取数据,POST 请求用于提交数据。


③ 幂等性:一般来说,GET 请求会被开发人员设计成 “幂等” 的,POST请求不被设计成 “幂等” 的,


幂等:数学上的术语,某个请求,执行一次和执行多次,在结果上没有区别。


④ 可缓存:一般来说,GET 请求会被缓存,POST 请求不会被缓存。


缓存:计算机若需要通过一些复杂的、大量的计算,来得到一些结果,如果这个结果的计算过程代价太大,就可以把这样的结果事先保存下来,下次直接使用,避免重复计算了。从而提升了效率,减少了消耗。


注意


可以看到,上面的四个细节上的差别,在开头上,我都用了【一般来说】。这是因为,GET 和 POST 在细节上的区别并不是绝对的,两者的差别都是受到了开发人员设计、浏览器、实现场景等因素的影响。所以,他们之间的一些差别本身就是可以相互转换的。总而言之,在大前提上,它们没有本质区别。


此外,关于两者在【传输的安全性、传输的数据量、传输的数据类型…】等问题上,官方文档并没有给出区别说明。还是那句话,两者无本质区别,若真的有差异,这是根据开发人员的设计、浏览器、服务器…来决定的。


4. HTTP 请求的其他方法


b935d3b8d51f48ae84549e44ec85dd7c.png


① PUT:与 POST 相似,只是具有幂等特性,一般用于更新

② DELETE:删除服务器指定资源

③ OPTIONS:返回服务器所支持的请求方法

④ HEAD:类似于GET,只不过响应体不返回,只返回响应头

⑤ TRACE:回显服务器端收到的请求,测试的时候会用到这个

⑥ CONNECT:预留,暂无使用


我们必须明确:在HTTP 请求中,用的最多的就是 GET 和 POST。而 HTTP 请求的其他方法,作为了解即可。


5. 认识 HTTP 请求中的报头


(1) Host


Host:表示服务器主机的地址和端口。一般来说,如果我们在浏览器中输入 URL,那么,HOST 表示的信息与 URL 中的内容是一样的,但也不绝对。


(2) Content-Length


Content-Length:表示请求中 body 中的数据长度,单位是字节。如果 body 内容为空,那么,在抓包的时候,也许就看不到这个 Content-Length.


(3) Content-Type


Content-Type:表示请求中 body 中的数据类型,常见的有三种。前面提到 body 一般存在于 POST 请求中,那么下面三种情况也常对应着 POST 请求中的 body.


① application/x-www-form-urlencoded


studentID=123&classID=456


② multipart/form-data


这种类型较为复杂,主要是用来提交文件的。


③ application/json


{
  "studentID": 123,
  "classID": 456,
  "age": 21,
  ...
  ...
}


(4) User-Agent


User-Agent ( UA ):表示浏览器 / 操作系统的属性。


这是我通过 chrome 浏览器查询信息后,抓包的结果:


User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36

【Windows NT 10.0】 表示 win10 的内核版本,【Win64;64】表示操作系统的版本信息,后面跟的是浏览器的版本信息。


UA 不仅能表示 PC 端的浏览器属性,还能表示移动端的浏览器属性。鉴于此,它能够区分当前设备是 PC 端 还是 移动端,从而对网页排版做出不同的尺寸。


(5) Referer


Referer:表示当前页面是从哪个页面跳转过来的。


(6) Cookie


Cookie 机制:当浏览器访问网页对应的服务器时,服务器会在 HTTP 的响应头中添加一个键值对传送给浏览器,往后每次访问此网页所属的网站时,都会在请求头中带着这个网站的所有 Cookie 值。


举个例子:你现在通过用户名和密码登录了 CSDN,这时,浏览器会向服务器发送请求;之后,服务器就会返回响应,而在响应的过程中,它给予了浏览器一个 “令牌”,告知浏览器,之后所以的操作都在你的用户名下,不管是浏览 CSDN 的文章也好、不管是自己写博客也好、不管是点赞收藏博客也好…这都基于你当前的用户名。如果要切换用户,那么只有 “退出登录” 才行。


这个过程和去医院看病很相似:到了医院先挂号,挂号时候需要提供身份证,同时得到了一张 “就诊卡”,这个就诊卡就相当于患者的 “令牌”。后续病人去各个科室进行检查、诊断、开药等操作,都不必再出示身份证了,只要凭就诊卡即可识别出当前患者的身份。看完病了之后,不想要就诊卡了,就可以注销这个卡,此时患者的身份和就诊卡的关联就销毁了。


6. body 正文


body 正文:正文中的内容是开发人员自定义的,所以,就算是很多明文的数据,也只有开发人员知道使用着什么逻辑,更别提密文了。


报头中的 Content-Type 和 Content-Length 即分别表示 body 正文的类型和字节长度。


三、HTTP 响应



HTTP 响应的基本格式


以下面图片为例:


8b14485aff8648fa8e5c066155fbfecf.png


HTTP 响应的基本格式和 HTTP 请求基本相似,一般分为四个部分:


① 首行


HTTP 响应的首行十分有特点:


【协议】+ / +【协议版本号】+ 空格 +【状态码】+ 【状态码描述】

② header 响应报头:每一行都是一个键值对。


③ 空行


④ 正文 body


1. 认识状态码(经典面试题)


状态码表示访问一个页面的结果,可能访问成功,也可能访问失败,也可能是其他的一些情况。


(1) 200 OK


200 这是一个最常见的状态码,表示访问成功。


在使用 fiddler 抓包的时候,如果成功访问某页面,那么 HTTP 的响应首行末尾就是 200 OK.


(2) 404 Not found


404 表示没有找到资源。在我们日常使用浏览器的时候,如果出现问题,很多情况下就是碰到了关于 “页面丢失的情况”,所以,404 还是较为常见的。


例如:下面的一幅图分别呈现了 搜狗访问出错和 B站访问出错,这个 404 也可以由开发人员自行设计。


79414f90ab5a479cac90acd0e6032402.png


(3) 403 Forbidden


403 表示访问被拒绝,有的页面通常需要用户具有一定的权限才能访问。


比方说:程序员使用 gitee 码云仓库,如果用户将一些仓库设为私有,那么其他用户访问这些私有仓库的时候,就会出现 403.


(4) 405 Method Not Allowed


前面我们已经学习了 HTTP 请求中所支持的方法,有 GET, POST, PUT, DELETE…等。一旦我们使用了这些方法,在我们的视角来看,这是没问题的。但访问对方的服务器,不一定都支持所有的方法,或者说,访问的服务器限制了用户使用一些方法。那么此时,就会出现 405.


(5) 500 Internal Server Error


500 表示服务器出现内部错误,一般是在服务器的代码执行过程中遇到了一些特殊情况,比方说:服务器异常崩溃。


(6) 504 Gateway Timeout


504 表示网关超时。具体来说,当服务器负载比较大的时候,服务器处理单条请求的时候消耗的时间就会很长,就可能会导致出现超时的情况。


例如:


双十一 “秒杀” 场景;省级 / 国家级考试后,网上查分数线的时刻。


(7) 302 Move temporarily


302 表示临时重定向。具体来说,在登录页面中会经常见到 302,其用于实现登陆成功后,自动跳转到的某个页面。而 head 响应报头中的 Location 字段,即表示要跳转到的某个页面。


普通用户在使用浏览器的时候,基本见不到 302,只有通过抓包才能看到,302 状态码相当于一个瞬移功能," 从某一个链接跳到另一个链接 "。


例如:我通过 Chrome 浏览器,使用网页登录 QQ 邮箱后,Location 字段就立即记录下来接着要跳转到哪个地址上,从而,浏览器就会根据 Location 中记录的 URL,立即访问这个 URL.


d768cc3a9243417db9783f916c38f2c7.png


(8) 301 Move parmanently


301 表示永久重定向。当浏览器收到这种响应时,后续的请求都会被自动改成新的地址,另外,301 也是通过 Location 字段来表示要重定向到的新地址。


状态码总结


d4d1c27fe8ab4499b646ccefef1a2a56.pnga94498fdb65643ef93b43aee0313b4d2.png



2. 认识 HTTP 响应中的报头


HTTP 响应中的报头和 HTTP 请求中的报头 相比,两者格式类似,都是键值对的形式。但 Content-Type 对应的类型有很大不同。


(1) Content-Type


响应中的 Content-Type 常见取值有以下几种:


text/html:          body 数据格式是 HTML
text/css:           body 数据格式是 CSS
application/javascript:   body 数据格式是 JavaScript
application/json:       body 数据格式是 JSON
image/png         body 数据格式是 图片经过特殊处理后的文本形式


3. body 正文


HTTP 响应中的 body 正文与 HTTP 请求中的 正文 相比,两者大不相同。body 正文常见的内容基于 Content-Type.


四、拓展



1. 多使用 fiddler 抓包


HTTP 协议比较抽象,如果我们真的想要理解 HTTP协议 的来龙去脉,还是以 【抓包为主】,毕竟实践出真知,并且抓包后为我们呈现的结果,可以很清晰地让我们理解到,整个页面通过网络,做了些什么事情。


2. CtrI + F5 和 F5


一个页面,不仅仅只有一个 HTML 文件,还会依赖很多其他的资源,例如:CSS, JS,图片…这些资源其实都是通过网络,下载到浏览器本地的。


为什么呢?


现在这个时代,经常使用浏览器的人都知道,很多网页做的非常精美。所以一个网页依赖的资源可能很多很大,网络传输速度又不快 ( 相对于访问内存 / 磁盘 ),这个时候加载页面就会比较慢。浏览器就会把这些依赖的资源直接缓存到本地,后续再访问的时候速度就快了(已经缓存过的资源,就不必重新下载了)


CtrI + F5 表示强制刷新。


不会重复利用缓存数据,直接清空缓存,把所有的资源重新下载。


F5 表示刷新。

但仍然会重复利用缓存的数据。


有时候我们抓包,如果抓不到想要的结果,就可以尝试在当前页面中,使用 CtrI + F5,来个强制刷新,这样会使得抓包效果好上很多。


相关实践学习
基于函数计算快速搭建Hexo博客系统
本场景介绍如何使用阿里云函数计算服务命令行工具快速搭建一个Hexo博客。
目录
相关文章
|
24天前
|
网络协议 Linux iOS开发
推荐:实现RTSP/RTMP/HLS/HTTP协议的轻量级流媒体框架,支持大并发连接请求
推荐:实现RTSP/RTMP/HLS/HTTP协议的轻量级流媒体框架,支持大并发连接请求
53 1
|
1月前
|
网络协议 Linux
HTTP协议基本原理简介(二)
HTTP协议基本原理简介(二)
23 1
|
1月前
|
前端开发
webpack如何设置devServer启动项目为https协议
webpack如何设置devServer启动项目为https协议
141 0
|
1月前
|
缓存 前端开发
HTTP协议基本原理简介(三)
HTTP协议基本原理简介(三)
15 1
|
7天前
|
缓存 网络协议
【计算机协议】第一章——HTTP协议详解
【计算机协议】第一章——HTTP协议详解
|
9天前
|
网络协议 Java API
深度剖析:Java网络编程中的TCP/IP与HTTP协议实践
【4月更文挑战第17天】Java网络编程重在TCP/IP和HTTP协议的应用。TCP提供可靠数据传输,通过Socket和ServerSocket实现;HTTP用于Web服务,常借助HttpURLConnection或Apache HttpClient。两者结合,构成网络服务基础。Java有多种高级API和框架(如Netty、Spring Boot)简化开发,助力高效、高并发的网络通信。
|
11天前
|
缓存 安全 网络协议
Http协议是什么
【4月更文挑战第12天】HTTP是用于从WWW服务器传输超文本到浏览器的协议,基于TCP/IP,特点包括无连接、无状态、面向对象、无阻塞和可缓存。它的工作原理是客户端发送请求,服务器处理后返回响应。自1989年创建以来,HTTP已发展支持多媒体内容传输,并通过HTTPS提供安全保护。学习更多可参考计算机网络技术文献。
18 6
|
13天前
|
存储 JSON 前端开发
网络原理(4)HTTP协议(下)
网络原理(4)HTTP协议
25 0
|
24天前
|
XML JSON JavaScript
推荐一个比较好用的c++版本http协议库-cpp-httplib
推荐一个比较好用的c++版本http协议库-cpp-httplib
37 1
|
1月前
|
运维 监控 算法
slb监听协议http
SLB的HTTP监听器用于处理HTTP请求,配置时选择协议类型为HTTP和前端端口(如80)。SLB根据负载算法将请求转发至健康后端服务器,并支持会话保持。通过`X-Forwarded-For`和`X-Forwarded-Proto`头处理请求信息。由于不涉及SSL/TLS,数据传输不安全,推荐升级至HTTPS以加密通信。SLB提供性能监控和故障排查工具,帮助运维管理。
26 5