HTTP详解

楠枬 2024-08-17 15:37:01 阅读 68

目录

HTTP是什么?

HTTP协议格式

抓包工具的原理

HTTP请求格式

HTTP响应格式

URL

URL是什么

URL encode

方法(method)

GET方法

POST方法

GET和POST的区别

其他方法

header

Host

Content-Length

Content-Type

User-Agent(简称UA)

Referer

Cookie

正文(body) 

状态码(status code)

200 OK

404 Not Found

403 Forbidden

405 Method Not Allowed

500 Internal Server Error

504 Getway Timeout

302 Move temporarily

301 Moved Permanently

构造 HTTP 请求

form 表单

ajax

第三方工具


HTTP是什么?

HTTP(Hypertext Transfer Protocol,超文本传输协议):是一种用于传输超文本数据(如 HTML、图片、视频等)的应用层协议。

什么是超文本?

超文本是一种文本类型,通过链接将文本、图片、视频等多媒体内容相互关联起来的文本形式,不仅包括文字内容,还可以通过链接(超链接)在文档之间或者文档内部进行非线性的、随意的跳转和浏览。简而言之,就是传输内容不仅仅是文本,还可以是一些其他的资源,如图片、视频、音频等二进制数据

发展和版本:

HTTP/1.0:初期标准,简单的请求-响应模型

HTTP/1.1:引入了持久连接、管道化(pipelining)和分块传输编码(chunked transfer encoding)等特性,提高了性能和效率

HTTP/2:基于 Google 的 SPDY 协议发展而来,引入了多路复用(multiplexing)、头部压缩(header compression)、服务器推送(server push)等新特性,进一步提升了性能

HTTP/3:基于 UDP 协议的 QUIC 协议发展而来,主要解决了 TCP 连接上的性能问题,如连接握手时延迟、队头阻塞等

 HTTP往往是基于传输层的 TCP 协议实现的(1.0 1.1 和 2 都基于TCP,3 基于 UDP实现

目前,主要使用的还是 HTTP1.1 和 HTTP2.0,因此,我们主要学习 1.1版本

我们平时打开一个网站时,就是通过 HTTP 协议来传输数据的

当前的 百度首页 是通过 https 来进行通信的,https 是在 http 基础上做了加密解密工作,关于 https 我们后面再进行学习

HTTP协议的交互过程,是非常典型的 “一问一答”,即一个HTTP请求,对应一个HTTP响应

当我们在浏览器中输入百度的 网址(URL)时,浏览器就向百度的服务器发送了一个 HTTP 请求,百度的服务器返回一个 HTTP 响应

这个响应结果被浏览器解析后,就展示成我们看到的页面内容

在这个过程中浏览器可能会向服务器发送多个 HTTP 请求,服务器会对应返回多个响应,这些响应中就包含了 页面 HTML、CSS、JavaScript、图片等信息 

我们可以通过浏览器的 开发者工具 观察到这个详细过程

单击右键,选择 “检查”,或通过 F12 打开浏览器的开发者工具,切换到 Network,再刷新页面,就可看到:

HTTP协议格式

HTTP是一个文本格式的协议,可以通过浏览器的 开发者工具Fiddler 等进行抓包,分析 HTTP 请求和响应的细节

在这里,以 Fiddler 进行抓包分析

左侧窗口显示了所有的 HTTP 请求/响应,可以选中某个请求查看详情

右侧上方显示了 HTTP 请求的报文内容,选择Raw可查看HTTP请求的原始数据

右侧下方显示了 HTTP 响应的报文内容,选择Raw可查看HTTP响应的原始数据

若想要查看请求或响应的详细数据,可点击 View in Notepad,通过记事本打开 

其中,蓝色的表示返回的是一个 html,往往是访问一个网站的入口请求,选中这个请求并双击,就能够看到明细 

请求明细:

响应明细:

在抓包观察响应数据时,可能会看到压缩后的数据:

网络传输中的"带宽" 是稀缺资源,因此,为了传输效率更高,往往会对数据进行压缩

点击

 

 即可进行解压,查看原始内容

分别用记事本打开:

请求

 响应:

抓包工具的原理

Fiddler 相当于一个 "代理",浏览器访问 baido.com 时,会把 HTTP 请求先发给 Fiddler,Fiddler 再将请求转发给 百度的服务器,百度的服务器返回数据时, Fiddler 那到返回的数据,再将数据交给浏览器

因此,Fiddler 对于浏览器 和 百度服务器之间交互的数据细节是非常清楚的

HTTP请求格式

HTTP请求包含了4个部分:

1. 首行

其中又包含三部分内容:

GET https://www.baidu.com/ HTTP/1.1

方法(method) + url + 版本,三个部分使用空格进行分割

2. 请求头(Header)

包含了关于请求的属性,冒号分割的键值对,每组属性之间使用换行(\n)分割 

关于其中的具体内容,后续进行详细介绍 

3. 空行

 分割请求头和请求体

4. 请求体(Request Body,可选)

一些请求可能会包含请求体,例如在 POST 请求中,用来发送表单数据或者上传文件等

这四个部分组合在一起构成了一个完整的HTTP请求,用于向服务器请求特定的资源或执行特定的操作

HTTP响应格式

1. 首行

HTTP/1.1 200 OK

也包含3部分内容:版本号 + 状态码 + 状态码描述(3个部分之间使用空格分割)

2. 响应头(Header)

包含了关于响应的属性,冒号分割的键值对,每组属性之间使用换行(\n)分割 

3. 空行

分割响应头和响应体 

4. 响应体(Response Body)

包含了实际的响应数据,如 HTML 页面、JSON 数据

协议格式总结

为什么 HTTP报文中存在 “空行”?

这是因为HTTP协议并没有规定报头部分的键值对有多少个,空行相当于是 报头的结束标记,或是报头与正文之间的分隔符。HTTP在传输层依赖TCP协议,TCP协议是面向字节流的,若没有这个空行,就会出现 "粘包问题"

URL

URL是什么

URL(Uniform Resource Locator,统一资源定位符):也就是平时俗称的网址,用于标识和定位互联网上资源的地址,是 Web 中访问资源的标准方式

示例:

https://www.example.com:443/path/to/resource?param1=value1&param2=value2#section1

 

 

 https:协议方案名,如 http、https 以及访问 mysql 时用的 jdbc:mysql

www.example.com:服务器地址,可以是域名,也可以是IP地址,域名会通过DNS系统解析成一个具体的IP地址

443:端口号,可以省略,当端口号省略时,浏览器会根据协议类型自动决定使用哪个端口,如 http协议默认使用 80 端口,https 协议默认使用 443 端口

/path/to/resource:带层次的文件路径

param1=value1&param2=value2:查询字符串(query string),本质是一个键值对结构,键值对之间使用&分割,键值之间使用=间隔,key和value的取值和个数,由我们自行约定,通过这种方式来自定制传输需要的信息给服务器

section1:片段标识符,针对请求内容做的补充说明,片段标识主要用于页面内跳转

URL中可以省略的部分

协议名:可以省略,省略后默认为 http://

IP地址 / 域名:在 HTML 中可以省略(如 img,link,script,a 标签的 src 或者 href 属性),省略后表示服务器的 ip / 域名 与当前 HTML 所属的 ip / 域名 一致

端口号:可以省略,省略后若是 http 协议,端口号自动设置为 80,若是 https 协议,端口号自动设为 443

带层次的文件路径:可以省略,省略后相当于 /,有些服务器会在发现 / 路径的时候自动访问 /index.html

查询字符串:可以省略

片段标识:可以省略

URL encode

像 / ? : 等这样的字符,已经被 url 当作特殊意义理解了,因此这些字符串不能随意出现

若某个参数中需要带有这些特殊字符,就必须先对特殊字符进行转义

一个中文字符由 UTF-8 或 GBK 这样的编码方式构成,虽然在 URL 中没有特殊含义,但是仍然需要进行转义,否则浏览器可能把 UTF-8 / GBK 编码中的某个字节当作 URL中的特殊字符

转义的规则:

将需要转码的字符转换为 16 进制,然后从右到左,去4位(不足4位直接处理),每2位作1位,前面加上 %,编码成 %XY 格式

如:

方法(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方法

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 请求的特点:

首行的第一部分为 POST

URL的 query string 一般为空,也可以不为空

header部分有若干键值对结构

body部分一般不为空,body部分的数据格式通过 header中的 Content-Type 指定,body的长度由header中的Content-Length指定

GET和POST的区别

(1)从本质上来说,GET和POST本质上没有区别,使用GET的场景,也可以替换成POST;使用POST的场景,也可以替换成GET,这取决于你的代码是如何实现的(部分服务器或浏览器某些情况下GET和POST不能很好地替换,但大部分情况下可以进行相互替换)

(2)从使用习惯上来说,GET通常没有body,POST通常有body。GET会将需要给服务器的补充信息放到 query string中(url中),而POST会将这些信息放到body中,但是 GET也可以将数据放到body(但有的服务器或浏览器可能不支持),POST也可以将数据放到 Query String(绝大多数服务器和浏览器都支持)

(3)从语义上来说,GET一般用于获取数据,POST一般用于提交数据(但实际使用时并不一定遵守上述要求)

(4)从幂等性来说,GET请求一般是幂等的,POST请求一般是不幂等的

什么是幂等?

每次输入的内容一定,输出的结果也一定,则称为幂等

每次输入的内容一定,输出的结果不一定,则不是幂等

若某个操作是幂等的,则意味着可以进行缓存,因此

(5)GET 可以被缓存,POST不能被缓存

其他方法

由于日常大部分使用的是GET和POST,其他方法就简单进行介绍

PUT:与POST相似,但具有幂等性,一般用于更新

DELETE:删除服务器指定资源

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

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

TRACE:回显服务器端收到的请求,测试时会使用到

CONNECT:预留,暂无使用

这些方法的 HTTP 请求可以使用 ajax 进行构造,也可以使用一些第三方工具

header

header得到整体格式是 键值对 结构

每个键值对占一行,键值对之间用冒号分割,每组属性之间使用换行(\n)分割 

报头的种类有很多,我们先学习一些常见的

Host

表示 服务器主机的地址和端口号

如:Host: www.baidu.com

Content-Length

表示 body 中的数据长度,通过 Content-Length 来处理 粘包问题,HTTP是基于 TCP 的,当连续传输多个 HTTP 数据报时,此时接收方的接收缓冲区里就会积累多个包的数据,应用程序在读取这些数据的时候需要明确包之间的边界,若是没有 body 的请求或响应,则直接使用 空行 作为分割符;若有 body,空行就不再是结束标记,而是从空行开始读取 body,而 body 要读取多长,就取决于 Content-Length

Content-Type

表示 body 中的数据格式

请求中常用的数据格式有:

application/x-www-urlencoded:

form表单提交的数据格式,此时body的格式形如:

id=1&username=zhangsan

application/json:

数据为json,body格式形如:

{"id":1,"username":"zhangsan"}

multipart/form-data:

通常用于提交图片或文件

响应中常用的数据格式有:

text/plain:纯文本格式

text/html:html格式

text/css:css格式

application/javascript:js格式

application/json:json格式

image/png:png格式

....

User-Agent(简称UA)

表示浏览器/操作系统的属性,描述了用户使用什么样的设备上网,如:

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

其中, Windows NT 10.0; Win64; x64 表示操作系统信息,AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 表示浏览器信息

Referer

表示这个页面是从哪个页面跳转过来的,如:

Referer: https://gitee.com/Deepgreen

若直接在浏览器中输入 URL,或直接通过收藏夹访问页面时没有 referer 的 

Cookie

Cookie 中存储了一个字符串,这个数据可能是客户端(网页)自行通过JS写入的,也可能来自服务器(服务器在HTTP响应的header中通过 Set-Cookie 字段给浏览器返回数据),其本质上是一个浏览器本地持久化存储数据的机制,往往可以通过这个字段实现 "身份标识" 的功能

HTTP 请求中的 Cookie 字段,就是把本地存储的 Cookie 信息发送到服务器,而 HTTP 响应中会有一个 Set-Cookie 字段,就是服务器告诉浏览器要在本地保存哪些信息

Cookie是从哪里来的?到哪里去?

是服务器返回给浏览器的,通常是首次访问或登录成功时返回给浏览器的,浏览器会将Cookie存储在本地主机的硬盘上,后续每次访问服务器都会带上 Cookie,不同的客户端,保存的 Cookie 是不同的,即使是同一个主机,使用不同的浏览器,Cookie大概率也是不同的

Cookie中存储的是什么?

存储的是键值对格式的数据,其中的键和值都是我们自行定义的,和 query string 类似

Cookie在浏览器是如何组织的?

Cookie在硬盘中保存,按照不同的域名为维度分别进行存储,如浏览器访问百度,会有一组 Cookie,而访问gitee,又会有一组Cookie

Cookie的用途是什么?

用于在客户端保存数据,其中最主要的就是保存用户的身份标识,服务器就可以通过标识来区分用户了,但一些敏感信息,如用户密码,不会在 Cookie 保存(不安全)

正文(body) 

正文中的内容格式与 header中的Content-Type 密切相关,大家可以通过抓包来进行观察

状态码(status code)

状态码用于HTTP响应中,表示访问一个页面的结果(访问成功,或是失败,或是其他情况)

接下来,我们来了解常见的状态码:

200 OK

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

我们通过抓包抓到的大部分结果都是 200,如:

404 Not Found

表示没有找到资源

在浏览器中输入一个URL,目的是为了访问对方服务器的一个资源,如果这个URL标识的资源不存在,则会出现 404,如:

 

403 Forbidden

表示访问被拒绝,有的页面通常需要用户具有一定的权限才能访问(例如 登录后才能进行访问),若用户没有进行登录直接访问,就可能会见到 403,如:

 

405 Method Not Allowed

表示方法不被允许,在前面我们学习了HTTP中所支持的方法,如 GET、POST等,但访问的服务器不一定都支持所有的方法,如,服务器只支持 GET 请求,但是却发送了 POST请求:

500 Internal Server Error

表示服务器出现内部错误,一般是服务器的代码执行过程中遇到一些特殊情况(服务器异常崩溃)

例如:

<code> @GetMapping("/test")

public String test() {

int a = 1 / 0;

return "test";

}

504 Getway Timeout

表示访问服务器超时,当服务器负载较大时,服务器处理单条请求时消耗的时间就会很长,就可能会导致出现超时的情况(例如 在进行"秒杀"活动时就可能会出现)

302 Move temporarily

表示临时重定向

什么是重定向?

重定向(Redirect):当用户请求访问一个网页或者资源时,服务器将其重定向到另一个位置或者另一个URL的过程,通常是由服务器端完成的,通过向用户返回特定的HTTP状态码和新的URL来实现

例如我们在进行登录时,当登录成功后就会自动跳转到主页

header 中会包含一个 Location 字段,表示要跳转到哪个页面

301 Moved Permanently

表示永久重定向,当浏览器接收到这种响应时,后续的请求都会被自动改成新的地址,若是永久重定向,浏览器就会将重定向的结果记录下来,后续再次访问,就可以直接访问重定向的目标地址,不必再多进行一次跳转了

301 也是通过 Location 字段来表示要重定向到的新地址

状态码总结:

状态码 类别 描述
1XX Informational(信息性状态码) 接收的请求正在处理
2XX Success(成功状态码) 请求正常处理完毕
3XX Redirection(重定向状态码) 需要进行附加操作以完成请求
4XX Client Error(客户端错误状态码) 服务器无法处理请求
5XX Server Error(服务器错误状态码) 服务器处理请求出错

构造 HTTP 请求

可以通过浏览器地址直接构造 GET 请求,如:直接在浏览器地址栏输入http://127.0.0.18080/index.html

form 表单

form(表单)是HTML中的一个常用标签,可以用于向服务器发送GET或POST请求

例如:发送get请求

<code> <form action="http://path/to/resource" method="GET">code>

<input type="text" name="username">code>

<input type="password" name="password">code>

<input type="submit" value="提交">code>

</form>

form 中的重要参数:

action:构造的HTTP请求的URL

method:构造的HTTP请求的方法是GET还是POST(form只支持 GET 和 POST)

input 的重要参数:

type:输入框的类型,text 表示文本,password 表示密码,submit表示提交按钮...

name:表示构造出的HTTP请求的 query string 的 key,query string 的 value就是输入框中输入的内容

value:input标签的值,对于 type 为 submit 类型来说,value 就对应了按钮上显示的文本

 页面展示效果:

填入数据,并点击提交:

构造的HTTP请求 

 form 与 http 请求之间的对应关系:

若想要发送 POST 请求,则只需要将 form 中的 method 修改为 POST

<code> <form action="http://path/to/resource" method="post">code>

<input type="text" name="username">code>

<input type="password" name="password">code>

<input type="submit" value="提交">code>

</form>

此时再次填入数据,并提交:

此时数据从 query string 移动到了 body

ajax

除了可以通过浏览器地址栏构造 GET 请求,form 表单构造 GET 和 POST 请求外,还可以通过 ajax 构造 HTTP 请求,且功能更加强大

ajax(Asynchronous JavaScript and XML)是一种用于创建快速动态网页的技术。通过在后台与服务器进行数据交换,可以实现网页的异步更新,使得页面可以在不重新加载整个页面的情况下更新部分内容。其特点是可以不需要 刷新页面 或 页面跳转 就能够进行数据传输

 此处使用的是 jquery 的 ajax,而不是原生 ajax

<code> <!-- 引入jquery -->

<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>code>

<script>

$.ajax({

url: "https://path/to/resource",

type: "get",

success: function(result) {

console.log("响应");

}

});

</script>

success 申明了一个回调函数,会在服务器响应返回到浏览器时触发该回调函数

若想要发送 POST 请求,需要设置 contentType(body 中的数据格式) 和 data(body 中的内容)

例如:发送 application/json 数据

<!-- 引入jquery -->

<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>code>

<script>

$.ajax({

url: "https://path/to/resource",

type: "post",

contentType: "application/json",

data: '{"id":1,"username":"zhangsan"}',

success: function(result) {

console.log("响应");

}

});

</script>

第三方工具

我们可以通过第三方工具很容易地构造出HTTP请求,如 postman、Apifox等工具

在这里,我们使用 postman 作为示例:

发送 GET 请求

 

发送 POST 请求



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。