当前位置: 首页 > news >正文

网络原理 - 11(HTTP/HTTPS - 2 - 请求)

目录

HTTP 请求(Request)

认识 URL

URL 基本格式

关于 URL encode

认识方法(method)

1. GET 方法

2. POST 方法

认识请求“报头”(header)

Host

Content-Length   Content-Type

User-Agent(简称 UA)

Referer

认识请求“正文”(body)

完!


HTTP 请求(Request)

认识 URL

URL 基本格式

URL 不仅仅是在 HTTP 中使用,回忆想想,我们之前在 JDBC 也使用过 URL:jdbc:mysql://127.0.0.1:3306/java110?characterEncoding=utf8&useSSL=false

平时我们俗称的“网址”,其实说的就是 URL(Uniform Resource Locator 统一资源定位符),描述一个互联网上的资源位置,即互联网上的每个文件都有一个唯一的 URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。(URL 的详细规则由因特网表述 RFC1738 进行约定~~)

我们上面的:https://www.baidu.com/ 

这是一个最简单的 URL,https 是协议的名称,www.baidu.com 是域名

我们如果抓一个百度里面的搜索内容请求如下:

此时的 URL 就不是上面那么简单了:在协议的名称,域名的后面,还跟了一长串字符~~ 称为查询字符串(query string),查询字符串中表达的意思,作为外人是无从得知的,这里面的内容就是写这个代码的程序员定义的~~

我们可以看到,在查询字符串中,也是键值对的格式。但此处的键值对,是使用 & 分割键值对,使用 = 来分割键和值~~

一个完整的 URL 结构如下:

http:协议方案名,常见的有 http 和 https,也有其他的类型(我们前面访问 mysql 的时候使用 jdbc:mysql)(可以省略,省略后默认为 http://)

user:pass:登录信息,之前是直接会把相关认证信息直接在 URL 中展示的,后来发现实在是不太安全~~ 现在都是通过单独的登陆页面来完成身份验证~~

www.example.jp:80:服务器地址,服务器端口号,这里的域名,也可以是 IP 地址,后面带有端口号,可以表示我们要访问服务器那个端口,如果 URL 中不带端口号,浏览器就会自动给一个默认的端口(这里的服务器端口,不是客户端中系统随机分配的那个),此处用什么端口作为默认值,取决于我们的协议是什么:http -- 80    https -- 443

dir/index.html:带有层次的文件路径

uid=1:查询字符串,是客户端给服务器传递信息的重要途径,这里的组织方式是按照键值对来组织的,这里面的键值对内容,是程序员自定义的~~

ch1:片段标识符,主要用于页面跳转,常用于通过不同的片段表示跳转到文档的不同章节

结合上述的 IP 地址,端口号,带层次的文件路径,查询字符串,就可以描述出一个网络资源了:

http://中北大学文韬餐厅:20/手抓饼/番茄手抓饼/?辣椒=少放&香菜=多放

关于 URL encode

在 query string 中都是程序员自定义的键值对,但在 URL 中,本身有些特殊符号具有特特定的含义: /   :   ?  @  .....

如果 URL 中的 query string 中也包含同样的符号,怎么办呢??? ==》 如果直接写进 query string 中,就可能会使服务器 / 浏览器解析失败!!

一个靠谱的办法,我们前面已经在代码中使用过了:对上述符号进行“转义”。包括中文字符或者是其他由 UTF-8 或者 GBK 这样的编码方式构成的字符,虽然在 URL 中没有特殊含义,但浏览器可能会把编码中的某个字节当作 URL 中的特殊符号,也需要进行转义~~

转义的规则如下:将需要转码的字符的转为 16 进制表示,前面加上 % 即可

比如我们搜索 C++:

可以看到,query string 中显示的是 C%2B%2B

我们可以通过 ASCII 码表发现,+ 的十六进度是 2B,则对应了 C++ ==》 C%2B%2B

我们也可以搜索一个女神

在上面虽然显示的 query string 直接是女神,是浏览器自动进行了解析,我们可以复制粘贴出来到文本文档就显示出来了:

我们“女神”进行 utf-8 编码:

结果相符~~

我们这里的 urlencode 编码是非常非常重要的~~ 在实际开发中,当我们要构造一个 URL 的时候,尤其是 URL 的 query string 中要包含中文的时候,务必要进行编码!!

认识方法(method)

请求的首行中,包括了 方法 URL 版本号

方法就描述了这次请求,想干啥(目的)

1. GET 方法

GET 是最常用的 HTTP 方法,常用于获取服务器上的某个资源(读操作)。在浏览器中直接输入 URL,此时浏览器就会发送出一个 GET 请求。另外,HTML 中的 link,img,script 等标签,也会触发 GET 请求。

使用 Fiddler 观察 GET 请求:

在浏览器访问百度主页,观察抓包结果:

我们可以看到,最上面蓝色的,是通过浏览器地址发送的 GET 请求,下面的

下面的一个写 baidu 域名相关的请求,有些是通过 HTML 中的 link/script/img 标签产生的。有些是通过 ajax 方式产生的。

我们选中第一条,观察请求的详细结果:

GET 请求的特点:

首行的第一部分为 GET

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

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

body 部分为空

2. POST 方法

POST 方法也是一种常见的方法,多用于提交用户输入的数据给服务器(例如登录页面)

我们可以登录 gitee 来进行一下抓包~

对第一个请求,点击查看详情

POST 请求的特点:

首行的第一部分为 POST

URL 的 query string 一般为空(可以不为空)

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

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

面试题:POST 和 GET 的区别

先盖棺定论:GET 和 POST 没有本质区别。使用 GET 的场景,也可以替换成 POST,使用 POST 的场景,也能替换成 GET(这里主要是取决于程序员代码是怎么写的,尤其是服务器和客户端都是同一个程序员实现的情况~~)(部分服务器 / 部分浏览器,在某些情况下 GET 和 POST 不能完美替换,但是大部分情况下,相互替换问题一般不大~~)

但是 GET 和 POST 还是在使用习惯上有一些区别的~~

1. GET 习惯于把数据放到 URL 的 query string 中。POST 习惯于把数据放到 body 中。

(GET 也可以把数据放到 body,POST 也可以把数据放到 query string -- 有些可能不支持,绝大部分都支持)

2. 语义上的区别。在标准文档中,GET 的语义是用来获取数据的,POST 的语义是给服务器传输数据的。(实际使用,当然还是程序员自己说了算~~)

3. 关于幂等性,在标准文档中,建议 GET 请求实现幂等的,POST 无要求。

(幂等:是一种数学术语,在计算机中也很常见~~ 即每次输入的内容一定,输出的结果也一定,就称为是幂等的,如果每次输入的内容一定,输出的结果不一定,就不是幂等的)

(GET 在实际开发中,也不一定非要实现幂等,标准是这么建议的,但我们可以不听标准的建议~~)

网上的一些不太准确的相关说法:

1. POST 比 GET 更加安全~~

论据:登录的时候,如果使用 GET,用户密码就会显示在 URL 中,此时会被别人看到,就不安全...

如今用户密码都会有一个单独的登录页面了,不会直接在 URL 中,即使是 POST ,即使没有显示子啊 URL 中,也是可以被黑客进行抓包获取的...真正保证安全性的关键在于加密!!

2. GET 传输的数据量小(存在上限),POST 传输的数据量更大

这句话描述的是以前的情况,以前是以前,现在是现在~~

实际上,HTTP 标准文档上明确说了,对于 GET,URL 的长度是不进行限制的,只不过是之前老版本的 IE 浏览器在实现的时候,URL 的长度有限制(现在已经没有了~~)

3. GET 只能携带文本数据,POST 可以携带二进制数据

这个说法,并不是完全错误,只是有一些局限性~~

URL 通过 query string 来携带数据

query string 是只能包含文本的,是对二进制数据进行 urlencode 了,自然就成为文本了。到了服务器再进行 urldecode,就能把数据还原成二进制。

POST 请求中,bodu 中虽然可以携带二进制数据,但也不是经常携带的,很多时候是对二进制数据进行 urlencode / base64 等等方式进行转码的~~

其他方法使用较少~~

认识请求“报头”(header)

header 的整体格式也是“键值对”结构

每个键值对占一行,键和值之间使用分号进行分割~

Host

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

(URL 中已经有 Host 了,这里的 Host 和 URL 中的 IP 地址 端口什么的,绝大部分情况下都是一样的~~)

Content-Length   Content-Type

Content-Length 表示 body 中的数据长度。

Content-Type 表示请求的 body 中的数据格式。

(和 body 密切相关,如果当前数据包没有 body,也就不会有这两个字段)

如果没有这两个字段,body 的请求/响应,就会直接使用空行作为分隔符了,如果有 body,空行就不是结束标志了,从空行开始来读取 body,body 要读多长就取决于 Content-Length,读完之后,这个包就结束了

Content - Type 中的常见选项:

请求中:

1) application/json:body 中的数据为 json 格式,形如:

{"username":"123456789","password":"xxx","code":"aaa","uuuid":"d110a05ccde65da13"}

2) application/x-www-form-urlencode:称为 form 表单,通过 HTML 中的 form 标签构造出来的一种格式,这种格式的特点是,把 query string 放到 body 中了

3) multipart/form-data:当需要在表单中上传文件,或者包含二进制数据的时候使用。在 HTML 的 form 标签中需要设置 enctype=“multipart/form=data“。

例如:

使用 boundary(边界标识符,如 ---------WebKitFormBoundaryrGKCBY7qhFd3TrwA)来分割不同表单数据部分。每个部分包含自身的元数据(如 Content-Disposition 指定数据类型和名称,Content-Type 指定具体的数据类型)。

响应中:

1) text/plain 纯文本

2) text/html   html 页面

3) text/css  css 页面

4) application/javascript js

5) application/json

6) image/png

7) image/jpg

.....................

补充:

我们后面自己写服务器程序返回网页,如果发现网页乱码,就可以检查一下是否是这里的编码方式没有设置或者是设置的不对~

User-Agent(简称 UA)

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

Windows NT 10.0 Win64; x64 ==> 操作系统信息

Chrome/121.0.0.0 Safari/537.36 Edg/135.0.0.0 ==》 浏览器信息~~

上古时期,UA 是非常关键的内容,由于计算机发展迅速,不同用户使用的上网设备,差异很大,UA 就可以表明该用户上网的设备具体是什么信息,如何用户使用的是比较老的设备,返回的页面就不含新特性,确保这个页面可以正确的访问出来。如果用户使用的是新设备,返回的页面就包含新的特性,确保这个页面体验感足够好~~

随着时间推移,浏览器现在都差不多了~~ 但 UA 仍然很有用,很多网站在 PC 端和手机端,由于其设备的大小区别,返回的页面布局也会有所差异,这就是通过 UA 来进行控制的~~

Referer

表示这个页面是从那个页面跳转过来的。在浏览器中,直接输入 URL 或者点击收藏夹打开的网页,此时是没有 Refere 的

举例:

我有个朋友~~~当年做的是广告页面~~~搜索广告中,都是按照点击计费的,用户每次点击广告,负责的企业都能赚钱,所以必须要记录某个广告在某个时间段内被点击多少次。

比如说在百度中搜索“肾虚”,当我们用户点击一下,百度就能到账 money~~

这个点击次数,百度和广告主都要进行统计~~

百度中,用户点击就会把请求发送到百度的计费服务台,通过记录日志就知道了~~

广告主中,就在他的服务器上记录日志,但一个广告,一般不会仅仅就找一家平台,他会找 360,搜狗等等~他怎么知道那些请求是百度的广告引流过来的呢??? ==》借助 referer 即可~~

问题来了 referer 是否会被篡改呢??? ==》 很有可能!!

因此就有了 HTTPS 的出现~~ 这个 S 其实是 SSL(网络中用于加密的协议~~)

加密就能把 header 和 body 都进行加密,网络上传输的就是密文了~~

其他人要想修改,就得先进行破解,就算能破解,也无法篡改,一旦进行修改操作,用户的浏览器就能感知到了~~~

Cookie 本质上是一个浏览器这边本地持久化存储数据的机制。

浏览器作为电脑上的一个程序,是可以直接读写本地磁盘文件的,系统提供了一个 API 操作文件。注意的是,浏览器上运行的网页,理论上也是可以通过浏览器提供的 API 来读写本地的磁盘文件,但是浏览器禁止了这种做法(浏览器并没有给网页提供这样的 API) (不安全~~ 万一黑客通过网页,直接把我们 C 盘中的学习资料删了怎么办??? /哭 /哭 ~~)

但话又说回来,有些网站,是需要把一些信息保存到浏览器这边的,比如当前登录的用户身份信息~~ 浏览器退而求其次,给网页提供了 API,但这个 API 只能是有限度的存储数据,而不能随意的访问文件系统~~

HTTP 请求中的 Cookie 字段,就是把本地存储的 Cookie 信息发送到服务器这边。

HTTP 响应中会有一个 Set-Cookie 字段,就算服务器告诉浏览器你要在本地保存那些信息。

上述的请求和响应字段,都是以键值对的形式进行的(程序员可以自定义~~)

Cookie 中存储了一个字符串,这个数据可能是客户端(网页)自行通过 JavaScript 写入的,也可能是来自于服务器(服务器在 HTTP 响应的 header 中通过 Set-Cookie 字段给浏览器返回数据)

一般可以通过这个字段来实现“身份标识”的功能。(每个不同的域名下都可以有不同的 Cookie,不同网站之间的 Cookie 并不冲突~)

举个例子:

Cookie 的作用,非常类似于超市买东西时候的购物卡流程~~

1. 注册会员(初始设置 Cookie)

当我们第一次去超市,注册称为会员之后,超市会给我们办一张会员卡,这就类比是服务器给客户端设置 Cookie。会员卡上记录了我们的信息,比如姓名,会员卡号,积分等等,这些信息就如同 Cookie 里面存储的用户标识等基础数据

2. 首次购物(第一次请求携带 Cookie)

当我们再收银台结账的时候,收银员会扫描我们的会员卡。这就类似于客户端向服务器发起请求的时候带上了 Cookie。收银员通过会员卡,就可以知道我们是会员,会根据会员的政策给我们积分或者相关的优惠,就像服务器根据 Cookie 里面的信息,来识别出用户,并作出响应的处理,比如提供个性化的页面展示或服务~~

3. 再次购物(后续请求携带 Cookie)

之后我们再去超市购物,结账的时候每次都出示会员卡。收银员每次都能够通过会员卡来了解到我们之前的购物记录,积分情况等,然后根据这些信息为我们提供服务~~比如提醒我们,积分快能兑换礼品了,或者根据我们的购物偏好,来推荐一些商品。这就如同客户端后续每次向服务器发送请求时,Cookie 持续发挥作用,让服务器可以基于之前的交互历史,持续为用户提供连贯,个性化的服务~~

流程图如下:

关于 Cookie 的几个重要结论:

1. Cookie 从哪里来???

服务器返回给浏览器的。通常都是首次访问/登录成功之后。

2. Cookie 到哪里去???

Cookie 会存储在浏览器本地主机的硬盘上。后续每次访问服务器都会带上 Cookie。不同的客户端,保存的 Cookie 是不同的,即使是同一个主机,使用不同的浏览器,Cookie 大概率也不同。

3. Cookie 中存储什么???

Cookie 以键值对的形式对数据进行存储。这里的内容都是程序员自定义的,和 query string 一样,外人无从理解~ 不同的网站的 Cookie 是不同的~

4. Cookie 在浏览器这边如何组织???

在硬盘本地保存,是按照不同的域名为维度,分别进行存储。

5. Cookie 的用途是什么???

用来在客户端保存数据,其中最主要的就是保存用户的身份标识,使得服务器可以通过标识来区分用户了,一般其他的业务不会存在 Cookie 中~~

我们可以通过抓包来观察一下页面登录的过程(以 gitee 为例):

1) 清除之前的 Cookie

2) 登录操作:

登录请求:

登录响应:

可以看到,响应中包含了 Set-Cookie 属性

其中我们重点看一下第二个,里面包含了一个 gitee-session-n 这样的属性,属性值是一串很长的加密之后的信息。这个信息就是用户当前登录的身份标识,也称为“令牌(token)”。

3) 访问其他页面

当我们登录成功之后,此时访问码云中的其他页面(比如个人主页),请求中就会带着刚刚获取到的 Cookie 信息。

我们的请求中的 Cookie 字段也包含了一个 gitee-session-n 属性,里面的值和刚才服务器返回的值相同,后续只要访问 gitee 这个网站,就会一直带着这个令牌,直到令牌过期/下次重新登录~~

比如我们此时再访问一个“我的星选集”,此时请求中的 Cookie 还是和之前一样的~~

理解登录过程:

这个过程再结合我们前面去超市买东西例子:

首次进入超市后,就是打开登录页面。当我们第一次结账提供手机号信息办会员卡的时候,就是输入用户名密码,点击登录,此时就得到了一张“会员卡”,这张会员卡就相当于是我们的“令牌”。

此后再去超市进行购物,积分兑换奖品等等操作,就不需要再提供手机号了,只需要凭会员卡就可以识别出我们的身份了。

当我们要搬家的时候,不想要会员卡了,就可以注销这个卡,此时我们的身份就和会员卡的关联就销毁了(类似于网站的退出登录操作)

当我们之后再搬回来,又想在超市买东西,就可以再办一张会员卡,此时就得到了一个新的令牌~~

认识请求“正文”(body)

正文中常见的就是我们上面 Content - Type 中的一些格式内容~~

完!

相关文章:

  • Shopify网上商店GraphQL Admin接口查询实战
  • idm 禁止自动更新提示(修改注册表)
  • Spring MVC中自定义日期类型格式转换器
  • 精益数据分析(32/126):电商指标优化与搜索策略解析
  • 【Python笔记 05】 if判断、比较运算符与逻辑运算符
  • Linux Ollama离线安装/更新教程-适用于国内快速下载Ollama最新版本(亲测好用)--适用于Qwen3 系列模型
  • 2025年- H12-Lc119-56.合并区间(普通数组)---java版
  • ROS2 学习
  • Uniapp:置顶
  • UDP数据报和TCP流套接字编程
  • 【网络原理】TCP异常处理(一):粘包问题
  • WSL2下Docker desktop的Cadvisor容器监控
  • 海思SD3403边缘计算AI核心设备概述
  • AI 边缘计算网关十大品牌
  • 高防CDN如何兼顾防护以及加速
  • 通用事件库IO多路复用技术选型与设计
  • MODSIM选型指南:汽车与航空航天企业如何选择仿真平台
  • 对 FormCalc 语言支持较好的 PDF 编辑软件综述
  • 基于蓝耘MaaS平台进行api调用创建本地智能ai
  • 【Web】如何解决 `npm run dev` 报错 `address already in use 127.0.0.1:9005` 的问题
  • 海尔智家一季度营收791亿元:净利润增长15%,海外市场收入增超12%
  • 中国贸促会:有近50%的外贸企业表示将减少对美业务
  • 女乘客遭顺风车甩客、深夜丢高速服务区,滴滴霸道回应:赔五百元
  • 我国首个大型通用光谱望远镜JUST在青海启动建设
  • 中公教育:去年全面扭亏,经营性现金流增长169.6%
  • 俄罗斯准备在没有先决条件的情况下与乌克兰进行谈判