网络原理(5):HTTP请求 – HTTP请求头(Host,Content-Length 和 Content-Type,User-Agent)

观前提醒

如果你对 http协议 的基本格式,有所了解的,可以直接看这篇博客。

如果你还不懂 http协议 以及 http协议 的基本格式,推荐你看完这篇博客再来看这篇博客:
网络原理(2):TCP/IP五层模型 – 应用层(HTTP协议初识)

同时,关于 HTTP请求 和 HTTP响应,其他常见属性的讲解博客,我编写了一个博客,里面存放着其他常见属性的博客链接:
网络原理(✨✨✨):HTTP协议 – HTTP请求和HTTP响应,常见的属性目录博客
希望你看完这篇博客之后,能点击这个博客链接,再学习其他的常见属性。

在这里插入图片描述
提前说明:请求头 和 响应头,两个都可以叫做报头

本篇博客,我们主要介绍 报头 中的三个常见属性:

  1. Host
  2. Content-Length 和 Content-Type
  3. User-Agent(简称 UA)

1. 请求头(报头)简介

请求头 和 响应头,两个都可以叫做报头以下,都叫做报头
报头,也叫做:header,它的整体的格式也是 “键值对” 结构
报头中的内容,分为很多行,每一行,就是一个键值对。

每个键值对占一行,键和值之间使用 :空格 分割。例如:键: 值

报头中,键和值,有哪些,都是由标准规定的,这一套标准是:RFC标准文档

既然每一个键值对,都是由标准指定,那么,每一个键值对,都有其自身的含义。
我们接下来,就介绍几个常见属性。

闲聊

关于 标准文档 这件事,在不仅仅在计算机行业中很常见,甚至在工业界都是很常见的。

有一句话说的好:三流公司做产品,一流公司做标准
三流公司做产品 => 卖产品赚钱
一流公司做标准 => 引领行业潮流,躺着赚钱(别人用你的技术,得付授权费)

这也是为什么美国不得不制裁华为的原因之一:
华为在 5G 通信领域,一直都是领头羊,提出了非常多的业界标准。
美国不敢任由它继续发展下去,必须制裁,按住华为发展的趋势。

2. Host

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

我们来使用 Fiddler 抓一个包,来看看,Host 长什么样子:
在这里插入图片描述
这是我登录 gitee 账号,抓取到的数据。

Host: gitee.com
Host 这是 键(key)
gitee.com 这是值(Value)

形如 gitee.com,表示的是:当前的请求访问的服务器在哪里。
Host,一般是使用 域名 来表示。
如果是使用IP地址来表示,一般是 一串数字+端口号
如果端口号使用的是默认的端口号,根据使用的协议决定:
HTTP协议 --> 80
HTTPS协议 --> 443

问题:URL的IP地址 和 Host

在这里插入图片描述
可以看到,URL的IP地址Host 表示的内容,是一样。
这两个属性,绝大部分是一致的

那么,问题来了:既然这两个属性,是一致,那我有一份不就完了吗,为什么会有两份?
答:有一些特殊场景,是不一致

代理

例如:使用了代理工具(梯子)

什么叫做代理?类似于处于请求和响应之间,中间商的意思。
如果使用了代理工具,请求会先发送给代理工具,再由代理工具,转发给服务器
HTTP请求的 URL 中的IP地址,会被代理工具进行修改

所以,即使我们 URL中的IP地址,被修改了,我们的 Host 是不变的
可以通过 Host 来获取到最原始的目标是什么,也就是原始的,正确的IP地址(域名)

加密

HTTP 协议中,传输的时候,可能会涉及到 “加密”(HTTPS)
URL 部分,是不会被加密的,被加密的是 header 和 body。

为什么要加密?
典型的场景就是:登录场景
登录的时候,请求中的方法,是 POST方法
而 POST方法,数据是存放到 body(正文)的。
加密,是为了保证你的账号密码,是安全的。

header 和 body 被加密之后,服务器收到请求之后,就可以做一个最终校验
由于 URL 中保存的是 原始的IP地址,服务器会验证 URL 中的 原始IP地址 和 header 中加密的 Host 的域名是否一致

闲聊:仅使用 HTTPS,能保证登录密码安全?

一般,登录密码这种,都是在 服务器 的代码中,业务层中,再次进行加密的。

依赖 HTTPS 这种操作,只能保证,数据传输到服务器的过程中,是安全的
但是,如果密码就明文保存到服务器上,服务器可能会被黑客攻击,严重的情况,会触发 拖库,也会造成密码泄露。

“ 拖库 ”是什么意思?
拖库就是指黑客通过各种社工手段、技术手段将数据库中敏感信息非法获取,一般这些敏感信息包括用户的账号信息如用户名、密码;身份信息如真实姓名、证件号码;通讯信息如电子邮箱、电话、住址等。

例如:你现在使用的 CSDN,就被拖过库,具体的事情,你百度搜索以下就知道了。

3. Content-Length 和 Content-Type

Content-Length :表示 body 中的数据长度单位是字节
Content-Type :表示请求中的 body 中的数据格式

这两个属性,其实是可有可无的,为什么?
Content-Length 和 Content-Type是否存在于报头,这要取决于,你这个请求中,是否有 body(正文)。

Content-Length

它的作用是什么?
首先,我们需要先明确一件事情:
HTTP 协议,传输层这里,是基于 TCP 实现的。
这个说法,建立在 HTTP协议 的版本号 <= 2.0 上。
从 HTTP3.0 ,就改用 UDP 实现了。

所谓的 HTTP 协议,就是把字符串构造成 HTTP协议 约定的格式。
什么样的格式?形如这样:

  1. 首行(包含:请求方法 URL 版本号)
  2. 请求头 (以键值对的方式组织)
  3. 空行
  4. 正文

把一串的字符串,根据上述约定的格式,写入到 TCP Socket 中。
至于如何使用 TCP Socket 来发送请求,你可以看我这篇博客:
Java网络编程(4):(socket API编程:TCP协议的 socket API – 回显程序)

对于 TCP 来说,与客户端建立一次连接,客户端可以发送多个请求给服务器。
服务器这边,收到数据的时候,就得区分一下,这一份数据的结束标志是什么,从哪里到哪里,算是一个完整的 http请求数据。

作用:

如果一个 HTTP请求,没有 body(正文),读到空行,就可以认为,空行是这一份请求数据的结束标志,可以结束读取了。

如果是有 body(正文)的 HTTP请求:

  1. 先读取到首行和header(报头)读到空行
  2. 解析header中的 Content-Length
  3. 根据 Content-Length 的值,读取 body 中,固定字节的长度
  4. 读完固定字节的长度,就结束本次HTTP请求的读取

如果没有 Content-Length,当读取HTTP请求时,就不知道body有多长,读取多少字节,才算结束。

Content-Type

Content-Type :表示请求中的 body 中的数据格式
它一般出现在 响应 中,会更多一点。

原因就是:请求,一般是不带有 body 的,有少数的请求,是带有 body 的,比如:比如:在某一个网站上,进行账号登录的时候。

作用:

Content-Type,提示了接收方该如何解析 body 中的数据。
因为 HTTP 协议,它能够携带的数据种类是比较多的,比如:
HTML,CSS,JavaScript,JSON,图片… …

当浏览器从服务器拿到一个数据包,浏览器该如何对这个数据包进行解析处理?
根据 Content-Type 表示的数据格式,浏览器会做对应的处理,以上述的数据种类为例:

HTML:浏览器会解析其中的 标签,把标签转换成界面显示
CSS:浏览器会解析其中的 选择器和属性,并且把这里指定的内容,应用到页面的样式上
Javascript:浏览器会通过 JavaScript引擎 ,解释并执行 JavaScript 中的逻辑
JSON:浏览器不会做任何处理(由对应的 JavaScript程序员 写的逻辑中,进行处理)
图片:浏览器会尝试按照 图片的二进制格式,解析出来并显示

Content-Type 表示的数据格式不同,浏览器做的工作,也是不同的。
同理,如果你是把请求发送给服务器,服务器也会根据请求报头的 Content-Type 属性,做不同的工作。

使用 Content-Type属性,来告诉浏览器,下一步,该怎么工作。

上述的数据种类,Content-Type所表示的属性值,也是不一样的:

HTML:text/html
CSS:test/css
Javascript:application/javascript
JSON:application/json
图片:image/png 或者 image/jpg

通过这些不同的 Content-Type ,就可以告诉浏览器,服务器,这个请求的 body,是什么样的数据格式,下一步该怎么做,明确了该做什么

以上,就是 Content-Type,起到的作用。

抓包演示:

想要通过抓包,抓取到 Content-Type 属性,一般要使用 Ctrl + F5(强制刷新)笔记本的键盘就是:Ctrl + Fn + F5

我们通过抓包,比如,强制刷新 gitee 页面:
HTML页面:
在这里插入图片描述

在这里插入图片描述
CSS:
在这里插入图片描述
在这里插入图片描述
JavaScript:
在这里插入图片描述
在这里插入图片描述
JSON在这里插入图片描述

你也可以在 Fiddler 抓取到的信息列中,看到 Content-Type:
在这里插入图片描述

补充:JavaScript代码混淆(了解即可,也可以不看)

通过上述抓包的演示,大家会看到,响应中的 body,数据格式是 JavaScript 的时候,你通常是看不懂它的代码是什么意思的。

但是,这些代码,都是合法的 JavaScript 语句,本质语法都是同一套。
只是看起来,和你学的 JavaScript 是不太一样的,因为这里运用到了一个机制:代码混淆

原因是:JavaScript 的代码,和 C++/Java 这样的代码,不一样。

C++/Java 这样的代码,会编译成二进制,再发布给用户。
用户拿到的是二进制的代码,用户想依据二进制的代码,还原出原始的代码是怎么样的,是非常麻烦的。

JavaScript 这样的代码,则是把原始的代码,直接由用户浏览器下载到,用户可以直接看到 JavaScript代码 的原始代码。
问题来了:程序员费劲千辛万苦写出来的代码,一下子被别人拿到了,如果别人基于你这个代码,也搭建出一样的网站,来和你竞争,抢你的饭碗,这是不是很不公平?

于是,就有专门的工具,能够将 JavaScript代码,做出变换
在不影响代码逻辑的情况下,把代码改乱。
让别人读起来,读懂的成本变高,破译难度增大。
别人想白嫖,还原出源代码,要很费劲。
破译成功的时间,比它自己重新写一个的时间,更长。
可以有效地保护代码版权的问题。

至于 HTML 和 CSS ,本身成本不高,而 JavaScript,本身是带有一定的业务逻辑,关于业务逻辑的代码,还是要保护的。

虽然现在的 ai工具,很发达,能够很容易的解析出来,但是,ai,毕竟也是最近两年,才火起来的。
JavaScript的混淆,各个公司,也肯定会采用新的手段,来保护代码的版权问题。

总结:

请求和响应,都会使用到 Content-Length 和 Content-Type,这两个 header 属性。

如果有 body,并且没有这两个属性,或者只有其中一个,都认为是 非法的 / 错误的 http报文

4. User-Agent(简称 UA)

我们先抓取 gitee 页面的一个 html 页面的请求:
在这里插入图片描述
在这里插入图片描述
我们看到的这一行信息,就是 User-Agent。

我们先来看看,这一行表示的信息,都是什么意思。

Mozilla/5.0 :firefox(火狐浏览器)
(Windows NT 10.0; Win64; x64):操作系统版本

  1. Windows NT 10.0:这是在 微软 中,Win10 的名字。
  2. Win64:表示 Windows系统,是 64 位的操作系统。
  3. x64:CPU,是 64 位的。

AppleWebKit/537.36:浏览器内核
(KHTML, like Gecko) :KHTML 另一种渲染引擎,这里表示兼容类似 Gecko(Firefox 所用引擎)的行为。
Chrome/126.0.0.0 :谷歌浏览器的版本
Safari/537.36 :苹果手机上的浏览器
Edg/126.0.0.0:微软自带的浏览器的版本

所以,这一行的信息,表示的就是:支持的浏览器版本,支持的操作系统版本。

User-Agent 里面表示:用户使用的设备,支持的浏览器版本 和 支持的操作系统版本

携带两个信息的来由

那么,为什么要有这两个信息呢?这两个信息的作用是什么呢?

User-Agent 诞生于互联网快速发展的早期。

最早,互联网主要是类似于 “报纸杂志” 的网站。
这个时候,浏览器只需要能够显示文本就行了。
后来,为了网站能够更加丰富,加入了很多新的东西,例如:图片、各种样式、JavaScript 实现各种逻辑、多媒体(音乐,视频)……

所以,那个年代,技术发展的是比较快的,正因为技术发展的太快,同一个时间段内:
有些用户的浏览器,版本是比较旧的,支持的功能少
有些用户的浏览器,版本是比较新的,支持的功能多

那么,问题就来到了程序员这里,如果程序员要开发一个网站,是要一个只能显示文字的网站,还是加入更多新的东西?
例如:例如:图片、各种样式、JavaScript 实现各种逻辑、多媒体(音乐,视频)……

如果支持的功能比较少,可能就打不过竞争对手
如果支持的功能多,旧版本的浏览器设备的用户,可能就展示不了
这就矛盾了,此时,通过 User-Agent,就能够解决这个问题。

作用(区分用户的设备情况):

上述的矛盾,程序员进行开发的时候,需要根据 用户 使用的设备,进行区分。
通过 User-Agent 中的浏览器版本,操作系统版本,区分出当前用户的设备情况,最多都支持哪些特性。

老的浏览器,返回功能少的网页,正确显示信息。
新的浏览器,返回功能多的网页,体验丰富。

到了 2025年,浏览器,都大差不差了,基本上,该有的功能,都有,现在 User-Agent ,用来区分浏览器版本的效果,就没有那么大了。

User-Agent,区分浏览器版本的作用,已经没有那么大的效果了。
但是,User-Agent,还有另外一个用途:根据操作系统,用来区分用户使用的设备是什么

  1. 如果你当前设备的操作系统,是 Windows / Mac,User-Agent 就能区分出,当前的设备是 PC(个人电脑)
  2. 如果你当前设备的操作系统,是 IOS / Android(安卓) / HarmonyOS(鸿蒙),User-Agent 就能区分出,当前的设备是 手机

PC和手机,展示页面的方式,是存在区别的。

  1. PC的屏幕,是比较宽的,展示页面的时候,可以显示的宽一点,使用鼠标操作电脑,操作精准,相关按钮,可以做的小一些。
  2. 手机的屏幕,是细长的,展示页面的时候,显示的就细长一些,用户点击屏幕操作手机,操作不精准,相关按钮,可以做的大一些。

这样,就可以通过 User-Agent,区分不同设备,显示不同的页面。

举例演示:

例如:PC版的搜狗浏览器 和 手机版的搜狗浏览器
在这里插入图片描述
在这里插入图片描述

补充说明:

根据操作系统,用来区分用户使用的设备是什么

  1. 如果你当前设备的操作系统,是 Windows / Mac,User-Agent 就能区分出,当前的设备是 PC(个人电脑)
  2. 如果你当前设备的操作系统,是 IOS / Android(安卓) / HarmonyOS(鸿蒙),User-Agent 就能区分出,当前的设备是 手机

上述的判断标准,并不是绝对的,也不是很准确
比如:使用的是 Android操作系统,就一定是手机吗?可以是安卓的平板吗?
当然可以。
那么,网站又是怎么去调整它的整个页面的大小呢?

这里就涉及到前端中的技术了,前端圈子中,有 “响应式编程” 这种编程方式
通过 CSS 中的 “ 媒体查询 ” 功能,感知到当前窗口的尺寸、宽度,通过不同的 尺寸、宽度,会自动设置不同样式,一个页面,就可以适配不同的窗口

关于 “响应式编程”,这里就不进行讲解了。

补充:64位操作系统 和 32位操作系统 的区别

从用户使用的角度来说:没啥区别

既然没区别,为什么会有 64位操作系统 和 32位操作系统?
原因:硬件发展到一定程度,对于 32位操作系统 / CPU 来说,能够支持的最大内存为 4G

说明一下:
你今天购买手机时,选择购买版本时,会有这样显示:
12 + 256,12 + 512 ,16 + 512 ……
前面的 12,16,叫做内存!!!
256,512,叫做 存储空间!!!
很多人说:256GB的内存,那不是正确的说法,只是这么多年了,都已经说习惯了,改不过来,其实,正确的说法是:
12GB的内存 + 256GB的存储空间

为什么对于 32位操作系统 / CPU 来说,能够支持的最大内存为 4G?
答:对于32位的 Windows 操作系统,其逻辑地址编码采用的地址位数是32位的,所提供的逻辑地址范围是 2^32 ,每一个逻辑地址对应一个字节2^32 个字节,换算一下,就是4GB
换算过程:

2^32 个字节(byte)= 2^22 KB
2^22 KB = 2^12 MB
2^12MB = 2^2GB = 4GB

随着时代的发展,4G内存,对于数据计算,数据处理来说,明显不够用了。
如果手机内存,要提升到 8GB内存 的话,就必须突破 32位操作系统/CPU 的限制,升级到 64位操作系统/CPU。

32位操作系统/CPU ,升级到 64位操作系统/CPU,对于计算机圈子来说,是一件惊天地地的大事,但是,对于普通人来说,完全没有感知,原因就是:Windows的兼容,做的好。

正常来说:
32位操作系统/CPU 运行的是 32位的程序
64位操作系统/CPU 运行的是 64位的程序
一旦升级到 64位操作系统/CPU,之前 32位的程序,就用不了了。
Windows的兼容性做的很好,64位的Windows系统,能够无缝的使用 32位的程序。
但是,Linux系统,就不可以这样了。

5. 总结

本篇博客,我们主要介绍 报头 中的三个常见属性:

  1. Host
  2. Content-Length 和 Content-Type
  3. User-Agent(简称 UA)

HTTP请求 和 HTTP响应,其他常见属性的讲解博客,我编写了一个博客,里面存放着其他常见属性的博客链接:
网络原理(✨✨✨):HTTP协议 – HTTP请求和HTTP响应,常见的属性目录博客
希望你看完这篇博客之后,能点击这个博客链接,再学习其他的常见属性。

最后,如果这篇博客能帮到你的,请你点点赞,有写错了,写的不好的,欢迎评论指出,谢谢!

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐