HTTP协议

2023年 9月 17日 74.9k 0

一.什么是HTTP协议以及HTTP协议格式?

1.什么是HTTP协议?

HTTP协议(超文本传输协议),是应用非常广泛的应用层协议。

在日常访问网站的过程中,就是通过HTTP协议来传输数据的,比如我们在浏览器中输入一个bilbil的“网址”(URL),那么浏览器就会给bilbil服务器发生一个HTTP请求,而bilbil服务器收到请求后也会放回一个HTTP响应,之后你看到的bilbil页面就是浏览器根据这个响应解析得到的结果。

那么我们如何能够看到HTTP请求和响应的具体内容呢?

2.HTTP协议格式

要看到HTTP协议的具体内容就要使用到抓包工具,我们以Fiddler为例。

2.1 什么是抓包工具?

其实Fiddler这样的抓包工具为什么能够详细的让我们看到HTTP协议的具体内容呢?
Fiddler就相当一个代理,浏览器发送请求的时候先发送给Fiddler,再发给服务器,而服务器放回响应的时候也是先交给Fiddler再给浏览器,所以Fiddler就相当于一个中间人一样,很明确双方的“交易”。

image.png

2.2 如何使用抓包工具?

当我们开启Fiddler后,Fiddler就会自动抓取每个HTTP协议。

image.png
举个例子,这个是我抓的bilbil网页的HTTP协议

在Fiddler左边是该主机的所有抓的包。

在右边的上方则是HTTP协议的请求。

在右边的下方则是HTTP协议的响应。

请求和响应都可以通过其右下角的 view in notepad进行转为文本查看。

2.3 HTTP请求的格式

这里我们以CSDN的登录为例

image.png
让我们看看这请求报文中都有什么:

1️⃣:首行中包括了方法即让我们知道是POST请求还是GET请求,URL即该网页的唯一资源地址(网址),还有版本号描述HTTP请求是什么版本的。

2️⃣:Header中正如我们看到的是各种各样的键值对,每一行都是一个键值对,键和值之前用:分割。

3️⃣:空行就是标志着header结束。

4️⃣:Body用来承载一些具体的数据(也可以是空字符串),此部分是由程序猿决定的。

image.png

2.4 HTTP响应的格式

我这里抓的是搜狗网页的响应报文

image.png

同样让我们来看看响应报文中的内容

1️⃣:首行中有版本号即HTTP的版本,状态码是描述此次发送的请求是否成功,状态码描述是对状态码加以说明。

2️⃣:Header与请求报文一样,都是各种各样的键值对,每行是一个键值对,键和值之前以:分割。

3️⃣:空行为Header的结束标记。

4️⃣:Body正文中是响应回浏览器的数据,可以是HTML,CSS,图片,视频等多种形式(允许为空字符串)。

image.png

💨 这里只是简单的显示一下HTTP请求和响应的格式,接下来就让我们详细的看看报文中的内容。

二.HTTP请求报文

1.URL

1.1 URL的基本格式

image.png

🕐:http://是协议方案名,常见的还有https,若是访问mysql时用的jdbc:mysql(可以省略,默认为http)。

🕑:user:paas是登录信息,但是现在的网站进行身份验证一般不会通过url进行了(缺乏安全性)。

🕒: www.example.jp表示服务器的IP地址,此处用域名表示,域名会通过DNS系统解析成一个具体的IP地址(在html中可以省略)。

🕓:80则是端口号(可以省略),若是被省略了浏览器会根据协议类型自动决定使用哪个端口(http协议使用80端口,https使用443端口)。

🕔:dir/index.html是带层次的文件路径,通过上面的服务器地址和端口号,就能够确定要访问的服务器是互联网上的哪个主机的哪个进程,而进程中可能有很多资源,通过带层次的文件路径就可以访问到进程中的一个具体的资源。

 🕕:uid=1为查询字符串(query string)为键值对,键值对之间以&分割,键和值之间以=分割,键值对的内容可以由程序猿定义(可以省略)。

🕖:ch1是片段标识符,一般用于小说页面的跳转(通过不同的片段标识符跳转到不同的章节)。

1.2 URL encode

image.png

像 / ? : 等这样的字符, 已经被url当做特殊意义理解了. 因此这些字符不能随意出现.
比如, 某个参数中需要带有这些特殊字符, 就必须先对特殊字符进行转义。
  一个中文字符由 UTF-8 或者 GBK 这样的编码方式构成, 虽然在 URL 中没有特殊含义,仍然需要进行转义. 否则浏览器可能把 UTF-8/GBK 编码中的某个字节当做 URL 中的特殊符号。

我们可以发现上方c++的+被转义成了%2B

转义规则如下:
将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做一
位,前面加上%,编码成%XY格式。

URL encode工具

2.方法

image.png

❗ 在HTTP中有许多的方法,其中GET和POST方法最为常用,接下来我们就来重点介绍一下这两个方法 

2.1 GET方法

GET方法是在协议中最常见的方法,表示从服务器中获取资源,比如我们在浏览器中输入了一个URL(网址),那么浏览器就会向对应的服务器发送一个GET请求,用于获取某些资源(html等)。

接下来让我们在Fiddler中抓一个GET请求看看

image.png

我们可以看到Fiddler出现了许多HTTPS和HTTP协议,这里我们看到的第一行也就是蓝色的那一行就是搜狗主页的关于HTML的请求,其他与sogo相关的请求有的是通过HTML里的link标签和script标签产生的,有些则是通过ajax产生的。

我们就对第一行请求进行分析

image.png

image.png

⭕ GET请求的特点:首行的第一部分为GET。

                                   URL的query string可以为空。

                                   Header部分有若干个键值对。

                                   Body部分为空。

❌ 网上对GET请求的URL长度的说法:get请求的长度最多为1024kb

      其实这样的说法是错误的。

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

也就是说关于URL的长度没有任何的限制。

实际上URL的长度与各浏览器HTTP服务器的实现有关,不同的浏览器对URL长度的限制也不一样,URL的长度是可配置的。 

2.2 POST方法

POST方法也是非常常见的方法,通常用于将数据提交给服务器(比如登录界面我们输入的账号,密码其实就是通过这样的方式发送给服务器的)。

可以通过HTML的form表单进行构造POST请求,也可以通过javascript的ajax进行构造POST请求

接下来同样使用Fiddler来抓一个post请求看看

image.png

image.png

⭕POST请求的特点:首行为POST方法。

                                     URL一般为空(也可以不为空)。

                                     Header部分为若干键值对。

                                     Body一般不为空,body内的数据格式为header里的content-type决定                                               body的长度由header里的content-length决定。

❌ 关于GET和POST的安全性问题

我们知道GET请求的body一般为空,传输数据是通过URL里的query string进行传输,而POST一般query string为空,传输数据是通过body来传输的,那么我们就会觉得GET更不安全,因为URL(网址)是可以直接看到的。

其实这种说法是错误的(写博客之前我也是这样理解的...)

即使POST的数据在body中,我们通过抓包工具同样可以看到,何谈安全呢?

💯 实际上是否安全取决于前端在传输密码等敏感信息时是否进行加密,和GET、POST无关。

 3.请求报头(Header)

通过上面介绍我们可以知道,header中是各种各样的键值对,键和值之间用:分割,而键值对有很多种,这里我们介绍几种重要的键值对。

3.1 HOST

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

image.png
一般来说端口号是可以省略的无非就是HTTP为80端口而HTTPS为443端口。

3.2 Content-length和Content-type

Countent-length:表示body中的数据长度。

Content-type:表示body中的数据格式(HTML,JSON)。

💨常见的数据格式:

1.application/x-www-form-urlencoded: form 表单提交的数据格式.
此时body中的数据类似为:title=test&content=hello
2.application/json: 数据为 json 格式
此时body中的数据类似为:{"username":"123456789","password":"xxxx"}

[关于content-type的详细情况](MIME types (IANA media types) - HTTP | MDN (mozilla.org))

3.3 User-Agent

表示浏览器/操作系统的属性

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/91.0.4472.77 Safari/537.36

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

3.4 Referer

表示这个页面是由哪个页面跳转过来的。

image.png

如果直接在浏览器中输入URL, 或者直接通过收藏夹访问页面时是没有 Referer 的.

3.5 Cookie

Cookie非常重要,首先我们要知道什么是Cookie?

我们都知道我们在逛网页的时候,有时需要存储一些数据,那么我们能直接让网页访问我们的硬盘吗?这显然是不行的,那么为了安全起见浏览器会禁止网页的JS访问我们的硬盘,但是为了能够在本地存储一些数据,那么就引出了Cookie。

⭕ Cookie是浏览器在本地存储数据的一种机制。

你一定经历过这样一个情况,比如你登录BILBIL或者是掘金,你之前登录过输入过账号密码,这次登录直接就进去了,不需要重新输入账号密码,这就是浏览器保存了我们的Cookie,里面有一些对应的信息,这个Cookie是服务器在你第一次的时候创建然后返回给浏览器的。

接下来我们就来看看BILBIL的Cookie.

Cookie是按照域名维度来维护的,不同的域名下存放不同的Cookie,一个网站发起的http请求可能是来自多个域名:

image.png

image.png

image.png

一般情况下Cookie是由键值对表示的和URL中的query string一样,上面的名称就是key,内容就是value。

Cookie中的键值对一般都是些简单的字符串,只能存一些简单的信息,比如:上次访问页面的时间、当前访问网页的次数、当前访问页面的身份信息。

搞明白了Cookie是什么之后我们还要明白两个问题。

Cookie从哪里来?

Cookie是服务器给的,服务器放回的响应报文中的header中有Set-Cookie报头,浏览器收到后会把这样的数据保存在本地中。

image.png

Cookie到哪里去?

其实Cookie也是回到服务器去,因为一个服务器对应着多个客户端(浏览器),那么他就需要一个身份标识来知道这个是谁,那么Cookie就是很好的身份标识,但浏览器保存了来自服务器的Cookie之后会将其保存在本地,等到下次要再访问该网页的时候直接将该Cookie发送给服务器,那么服务器就可以知道这个是谁了(保证Cookie唯一性即可)。

💨我们平时的登录操作其实就是这个过程。

image.png

4.正文(body)

正文部分没什么好讲的就是正文的数据类型对应着上述header中content-type的类型。

而有的请求中像GET请求甚至没有body部分。 

三.HTTP响应报文

1.状态码(status code)

状态码表示访问一个页面的结果(是成功还是失败,还是一些其他的情况).

以下是一些常见的状态码:

200 OK

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

image.png

404 Not Found

表示没有找到资源。

当我们输入一个错误的URL后就会出现404 not founud

image.png

403 Forbidden

表示访问被拒绝,有的网页需要用户有一定的权限才能进行访问,比如为需要登录的网页未登录直接访问就可能见到403.

302 Move temporarily

临时重定向。
理解重定向:重定向就类似手机号码中的“呼叫转移”功能,我原来的手机号换了一个,那么我的朋友一定是打我原来的那个手机号,那么我只需要去营业厅办理一个呼叫转移业务就可以让打到之前电话号码的人,自动转移到现在的电话号码。

在登陆页面中经常会见到 302. 用于实现登陆成功后自动跳转到主页.

💨 小结:

image.png

2.响应报头(Header) 

响应报头与请求报头基本一样

在content-type中响应报头出现的形式是这样的:

image.png

text/html : body 数据格式是 HTML
text/css : body 数据格式是 CSS
application/javascript : body 数据格式是 JavaScript
application/json : body 数据格式是 JSON

[关于content-type的详细情况](MIME types (IANA media types) - HTTP | MDN (mozilla.org))

3.响应正文(body)

正文的具体格式取决于 Content-Type.

text/html : body 数据格式是 HTML

image.png

text/css : body 数据格式是 CSS

类似这种:
@font-face{font-family:element-icons;src:url(../../static/fonts/element
icons.535877f5.woff) format("woff"),url(../../static/fonts/element
icons.732389de.ttf) format("truetype");font-weight:400;font-style:normal}
[class*=" el-icon-"],
.........

application/json : body 数据格式是 JSON

image.png

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论