JavaWeb | HTTP 协议请求与响应格式

一、HTTP 是什么

计算机网络核心概念:网络协议
网络协议种类非常多,其中一些耳熟能详的,IP,TCP,UD… 其中还有一个应用非常广泛的协议HTTP,HTTP 协议大概率是咱们日后开发中用的最多的协议

HTTP : (全称为 “超文本传输协议”) 是一种应用非常广泛的 应用层协议

HTTP 处于 TCP / IP 五层协议栈的应用层
HTTP 在传输层是基于TCP的 (不够严谨,HTTP/1,HTTP/2 是基于TCP最新版本是 HTTP/3 是基于 UDP,但是当下互联网上绝大部分使用的 HTTP 都是 HTTP/1.1 )

传输层协议 ,主要关注的是端对端之间的数据传输。TCP,重点关注的是可靠传输
应用层协议 ,则是站在程序应用的角度,要对传输的数据,来进行具体的使用

应用层协议,很多时候是程序猿自定制的,根据实际的需求场景,来设计协议

但是,程序猿大的圈子里,水平参差不齐
于是有些大佬就发明了一些很好用的协议,直接让大家照搬,HTTP 就是其中的一个典型代表

HTTP 虽然是已经设计好的,自身的可扩展性是非常强,可以根据实际需要,让程序猿传输各种自定义的数据信息

HTTP 具体的应用场景,大家天天都在用,只要你打开浏览器,随便打开一个网站,这个时候其实你就用到了 HTTP
或者你打开一个手机 APP,随便加载一些数据,这个时候其实你也大概率用到了 HTTP


二、HTTP 协议格式

1、协议格式

协议格式:数据具体是怎么组织的

UDP :报头 (源端口,目的端口,长度,校验和)+载荷

UDP / TCP / IP 这些协议都是属于 “二进制” 的协议,经常要理解到二进制的 bit 位

HTTP 则是一个文本格式的协议 (不需要去理解具体的二进制位,而只是理解文本的格式即可) (文本格式,所以更方便于人肉眼来观察)

如何才能看到 HTTP 的报文格式?

  • 其实可以借助一些 “抓包工具” 来获取到具体的 HTTP 交互过程中,请求和响应

TCP / UDP 这些,也是可以借助抓包工具来分析的

抓包工具,其实就是一个第三方的程序,在这个网络通信的过程中,类似于 “代理” 一样。例如我在宿舍,不想去买饭,就叫外卖送到宿舍,这个场景中,送外卖的人就是代理

在这里插入图片描述

请求和响应,都是要路过代理的
这个时候在代理上,就很容易获取到请求和响应的详细内容
因此,抓包工具就是一个代理,抓包工具就很容易的能够获取到,传输过程中的网络上的详细数据


2、抓包工具 Fiddler

Fiddler 是一个专门抓 HTTP 的抓包工具,没法抓到 TCP/UDP/IP… 要想抓这些,需要使用 wireshark 这样的工具

在这里插入图片描述

Fiddler 左侧 ,是一个列表,显示了当前抓到的所有的 HTTP / HTTPS 的数据报。HTTPS 是 HTTP 的孪生兄弟,HTTPS 就只是在 HTTP 的基础上,引入了加密机制

当选中左侧列表中的某个条目,并双击的时候,右侧就会显示这个条目的详细信息

请求:

在这里插入图片描述

在这里插入图片描述

这个标签页的选项,就表示了当前使用什么样的格式来显示 HTTP 请求,咱们用的最多的就是 Raw 这个选项
选择 Raw 看到的就是 HTTP 请求数据的本体
选择其他的选项,相当于 Fiddler 对数据进行了一些加工,调整了格式

点击 Row 原始数据就出来了!!
但是,太小了,看不清!! 可以点击旁边的 view in Note

在这里插入图片描述

以上就是 HTTP 请求的原始模样
如果你往 TCP socket 中,按照上述格式来构造数据,并写入 socket,其实本质上就相当于构造了一个 HTTP 请求

响应:

在这里插入图片描述

针对响应,也有很多的选项,此处要选择 Raw,才能看到本体

在这里插入图片描述

看到的本体好像是乱码 ?乱码其实是压缩之后的结果
一个服务器,最贵的硬件资源,其实是网络带宽 ,像这些HTTP响应,经常会很大,就比较占用带宽。为了能够提高效率,经常服务器会返回 “压缩之后” 的数据,由浏览器收到之后再来解压缩

在这里插入图片描述

点此按钮解压缩:

在这里插入图片描述

注意:

1、Fiddler 刚安装好的时候,默认没有启用 HTTPS ,如果你抓到了 HTTPS 的包,就会出现类似的情况,

在这里插入图片描述

当下网络上的大部分的网站都是 HTTPS ,如果不开启 HTTPS,其实就基本没啥可抓的了

在这里插入图片描述

2、Fiddler 可能会提醒你,要安装 xxx 证书 (一串英文.…….),一定要点是!!!

3、Fiddler 作为一个代理,是和其他的代理程序冲突的
如果你的电脑上也安装了其他代理程序 / 插件,就可能导致 Fiddler 失效(啥也抓不着),证你使用 fiddler的时候,要先退出相关的程序

安全问题:

  • 看对应的应用程序,是否对用户名密码进行了加密,如果没加密,就能获取到
    通过抓包,就能拿到当前的主机上的网络通信的数据
    而且,这个抓包,不一定非得在你的电脑上,也可以在通信链路的中间节点上
  • 如何解决这个问题,就需要在应用层这里加密

在这里插入图片描述

https:

确实是加密了,确实是在保障安全,但是 https 主要是防止篡改 ,而不是防止被窃取 [主要目的]


3、HTTP 请求格式

在这里插入图片描述

请求分成 4 个部分:

  • 请求行(首行) ,包含三个部分:

    • 1、 HTTP 的方法,方法大概描述了这个请求想干什么,``GET` 意思就是想从服务器获取到某个东西
    • 2、 URL 描述了要访问的网络上的资源具体是在哪
    • 3、 版本号, HTTP/1.1 表示当前使用的 HTTP 的版本是 1.1,1.1 是当下最主流的版本,还可能是 1.0 / 2 / 3
  • 请求头 (header),包含了很多行

    • 每一行都是一个键值对
    • 键和值之间使用 :空格 来分割
      键值对,计算机中的一个非常非常非常重要的概念
    • 这里的键值对个数是不固定的 (有可能多,也有可能少),不同的键和值,表示的含义,也不同 (后面会介绍一些常见的键值对的含义
  • 空行 :相当于请求头的结束标记
    类似于链表的 null

  • 请求正文(body) :可选的,不一定有

使用 fiddler 的一个小技巧:

  • 左侧的列表会一直持续的抓到新的结果 ,很快列表就会很大 (很多网站都在不停的和服务器交互,甚至说你电脑上的有些其他程序,也在偷偷的和人家的服务器使用 HTTP 交互)
  • 很多时候要进行清屏 ,选中一条记录,然后 ctrl + a 全选,然后按 delete 删除

一个简单的点击登录操作,就会让浏览器和码云服务器之间进行 N 多次交互,这是常态
就需要找到咱们想关注的请求,响应

在这里插入图片描述


4、HTTP 响应格式

在这里插入图片描述

  • 首行 :包含了3个部分

    • 1、 版本号 HTTP/1.1

    • 2、200 状态码,描述了这个响应,是一个表示 “成功的” 还是 "失败的”,以及不同的状态码,描述了失败的原因

    • 3、OK 状态码的描述 ,通过一个 / 一组简单的单词,来描述当前的状态码的含义

  • 响应头(header)

    • 也是键值对结构,每个键值对占一行,
    • 每个键和值之间使用 :空格 来分割,
    • 响应头中的键值对个数,也是不确定的。不同的键值对表示不同的含义
  • 空行
    表示响应头的结束标记

  • 响应正文(body)

    • 服务器返回给客户端的具体数据
    • 这里的东西可能有各种不同的格式 ,其中最常见的格式,html !!

三、HTTP 请求 (Request)

1、URL

  • 平时我们俗称的 “网址” 其实就是说的 URL (Uniform Resource Locator 统一资源定位符)
  • 互联网上的每个文件都有一个唯一的URL,既要明确主机是谁,又要明确取主机上的哪个资源

1.1、URL 基本格式

在这里插入图片描述

1、协议方案名:

  • 描述了当前这个 URL 是给哪个协议来使用的

  • http://给HTTP用的
    https://给HTTPS 用的
    jdbc:mysql://给jdbc:mysql使用的

2、登录信息:

  • 这个部分现在很少会用到,上古时期的时候,上网,会在这里体现用户名密码

3、服务器地址

  • 当前要访问的主机是什么,这里可以是一个 IP 地址,也可以是域名

4、服务器端口号

  • 表示当前要访问的主机上的哪个应用程序 (端口号大部分情况下是省略的)
  • 省略的时候,不是说没有,而是浏览器会自动赋予一个默认值 ,对于 http 开头的 URL,就会使用 80 端口作为默认值,对于 https 开头的 URL,就会使用 443 端口作为默认值

5、带层次的文件路径

  • 文件路径,描述了当前要访问的服务器的资源是啥
  • 虽然请求的 URL 中,写的是一个文件路径,但是不一定服务器上就真存在一个对应的文件。这个文件可能是一个真实的,在磁盘上存在的文件,也可能是虚拟的,由服务器代码,构造出的一个动态数据

上述的 IP地址+端口+带层次的文件路径 其实就描述了一个网络上具体的资源,但是在这个基础之上,还可以携带一些其他的要求,也就是后面的参数

6、查询字符串

  • 本质上是浏览器 / 客户端,给服务器传递的自定义的信息,相当于对获取到的资源提出了进一步的要求

  • 查询字符串的内容,本质上也是键值对结构,完全是程序猿自己定义的 ,外人不认识。例如:spm=1001.2014.3001.5502,键:spm,值:1001.2014.3001.5502,多个键值对以取地址符分隔

  • 查询字符串 和 路径 之间使用 ? 来分割

  • 路径就是 / ,查询字符串(query stirng) 没有 https://www.sogou.com/

    路径 web,查询字符串是后面到结束, https://www.sogou.com/web?query=fiddler&_asf=www.sogou.com&_ast=&w=01015002&p=40040108&ie=utf8&from=index-nologin&s_from=index&oq=&ri=0&sourceid=sugg&suguuid=&sut=0&sst0=1652343501136&lkt=0%2C0%2C0&sugsuv=1623569485720894&sugtime=1652343501136

    路径qq_56884023/article/details/124481401,查询字符串是后面到结束 https://blog.csdn.net/qq_56884023/article/details/124481401?spm=1001.2014.3001.5502

7、片段标识符

  • 描述了要访问当前 html 页面中哪个具体的子部分,能够控制浏览器滚动到相关位置

URL 中的可省略部分:

  • 协议名: 可以省略, 省略后默认为 http://
  • ip 地址 / 域名: 在 HTML 中可以省略(比如 img, link, script, a 标签的 src 或者 href 属性). 省略后表示服务器的 ip / 域名与当前 HTML 所属的 ip / 域名一致.
  • 端口号: 可以省略. 省略后如果是 http 协议, 端口号自动设为 80; 如果是 https 协议, 端口号自动设为 443.
  • 带层次的文件路径: 可以省略. 省略后相当于 / . 有些服务器会在发现 / 路径的时候自动访问/index.html
  • 查询字符串: 可以省略
  • 片段标识: 可以省略

URL 小结:

  • 对于 URL 来说,里面的结构看起来比较复杂,其实最重要的,和开发最关系紧密的,主要就是四个部分
    • ip 地址 / 域名
    • 端口号(经常是小透明)
    • 带层次结构的路径
    • query string 查询字符串 (这两个是和写代码密切相关的!!!)

1.2、URL encode / decode

  • 当 query string 中如果包含了特殊字符,就需要对特殊字符进行转义
  • 这个转义的过程,就叫做 url encode。反之,把转义后的内容还原回来,就叫做 url decode

url 里面是有很多特殊含义的符号的,/: ? &= … 这些符号都是在 URL 中具有特定含义的
万一,query string 里也包含这类特殊符号,就可能导致URL被解析失败!!!

当我们在 sogou 中搜索 C++ 的时候,可以看到,URL 中的 query string 里面,有一个键值对,就表示了查询词内容

https://www.sogou.com/web?query=C%2B%2B&_ast=1652345880&_asf=www.sogou.c …

%2B 其实就是 + 通过url encode 转义之后得到的结果。字符 + 的 ascii 的 16 进制表示,正是 2B (B 就是十六进制符号,相当于十进制的 11)

在实际开发的时候,尤其是前后端交互的时候,尤其是需要通过 URL 给服务器传递一些信息的时候,一定要针对里面的特殊符号进行 url encode。不仅仅是标点符号,还有中文字符
如果不转义,就可能会带来问题

  • 一个中文字符由 UTF-8 或者 GBK 这样的编码方式构成,虽然在 URL 中没有特殊含义,但是仍然需要进行转义,否则浏览器可能把 UTF-8/GBK 编码中的某个字节当做 URL 中的特殊符号
  • 转义的规则如下:将需要转码的字符转为 16 进制,然后从右到左,取4位 (不足4位直接处理),每2位做一位,前面加上%,编码成%XY格式,每个字节都分别这样处理

例如搜狗的 a 标签,有个 href 属性,包含了用户的查询词,如果页面中没有对中文查询词进行 urlencode 处理,就会导致在有些浏览器上,用户点击之后,不能正确跳转

在这里插入图片描述


2、方法

这里只是罗列到了 1.1,后续的 2 3 版本暂时不考虑

在这里插入图片描述

HTTP 协议的方法非常多!!!
但是最最常用的,也就是 GETPOST。GET 独占八斗,POST 占一斗,剩下的其他的方法,分这一斗

  • PUT 与 POST 相似,只是具有幂等特性,一般用于更新
  • DELETE 删除服务器指定资源
  • OPTIONS 返回服务器所支持的请求方法
  • HEAD 类似于GET,只不过响应体不返回,只返回响应头
  • TRACE 回显服务器端收到的请求,测试的时候会用到这个
  • CONNECT 预留,暂无使用
  • (注意,只是期望如此)

2.1、语义

HTTP 中引入这些方法,初衷 是为了表示不同的"语义",语义:是否有特定的含义

例如 HTML:h3, p, a, img… 语义化标签,div span 无语义标签

理想很丰满,但是现实很骨感
设计 HTTP 的大佬希望程序猿能够按照 HTTP 语义来使用这里的各种方法
但是随着时间的推移,使用就走形了,现在大家写代码,基本都是 GET / POST 一把梭,基本没咋考虑语义的事情
正因为如此,也就导致了多种 HTTP 方法之间的界限,就变的模糊了

GET 也可以给服务器送个东西,POST 也可以从服务器拿个东西


2.2、经典面试题:谈谈 GET 和 POST 的区别

第一句话,先盖棺定论!! GET 和 POST 没有本质区别!!!
具体来说,相当于是 GET 能使用的场景,也能替换成 POST,POST 使用的场景,也能替换成 GET但是细节上,还是有一些区别的

  1. 语义上的区别
    GET通常用来取数据,POST通常用来上传数据。现状是,GET也经常用来上传数据,POST也经常用来获取数据

  2. 通常情况下,GET 是没有 body,GET 通过 query string 向服务器传递数据
    通常情况下,POST 是有 body 的,POST 通过 body 向服务器传递数据,但是 POST 没有 query string

    • 如果我就想让 GET 有 body,(自己构造一个带 body 的 GET 请求),或者就想让 POST 带有 query string,完全可以
      不是强制性的区别,只是习惯用法,你可以遵守习惯,也可以打破习惯。像有些公司,统一都是使用 POST 来处理所有的请求
  3. GET 请求─般是幂等的,POST 请求一般是不幂等的, (也不是强制要求,而是建议)

    • 幂等: 是数学上的术语,每次你相同的输入,得到的输出结果是确定的。不幂等:每次你相同的输入,得到的结果不确定
  4. GET 可以被缓存,POST 不能被缓存

    • 提前把结果记住,如果是幂等的,记住结果是很有用的,节省了下次访问的开销。如果不是幂等的,就不应该去记
      能不能缓存和能不能幂等是有关联的,如果请求本身都不是幂等,就不能缓存

在这里插入图片描述

例如获取到的广告数据,虽然也是通过 GET 拿到的,但是绝对不能进行缓存!! 必须要实时计算,得保证合适的用户出合适的广告,出的广告也得符合广告主的投放规则

注意:网上最典型的错误:

  • GET 请求传递的数据长度有上限 (URL 有上限),POST 没有上限
    错误的!!! HTTP标准文档中,明文规定,标准本身不限制 URL 的长度 (网上流传这个说法的原因是,上古时期的浏览器实现,没有完全遵守标准导致的… 不适合于现代的浏览器…)

3、请求 “报头” (header)

  • header 里面是一些键值对,不同的键值对表示了不同的含义
  • 当前这里的键值对种类很多,以下是一些简单常见的

3.1、Host

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

Host: www.sogou.com。域名是可以通过 DNS 来转成 IP 地址的


3.2、Content-Length、Content-Type

  • Content-Length 表示 body 中的数据长度
  • Content-Type 表示请求的 body 中的数据格式

这两个属性是在描述 body ,如果你的请求里就没有 body(GET),也就不需要这两个字段了!!!
一般 POST 都是带 body,一般登录都是基于 POST 来实现的!!

在这里插入图片描述

为什么登录,是使用 POST 实现? 使用 GET 能不能实现登录呢?? 使用 GET 是完全可以实现登录功能的!!

为啥还主要使用POST?
登录肯定就要给服务器传递用户名和密码,如果是 GET,用户名密码习惯上就会放到 URL 的 query string 中来传递,
此时浏览器的地址栏里的路径,就可能变的很长一串)
(这个时候,用户体验可能就不太好)

尤其是早期的很多网站,就是把密码明文提交的
如果密码就明文的出现在 URL 中,其实就看起来就非常不好

POST 数据在 body 中,用户是不能直接看到的,body 里你放啥东西对于用户的影响都是非常小的

网上有种说法:使用 POST 实现登录,是因为 POST 比 GET 更安全,这种说法是完全不对的,安全不安全,取决于你的数据是否是明文传输,是否是加密过了

常见选项:

  1. application/x-www-form-urlencoded : form 表单提交的数据格式,此时 body 的格式形如:

    • title=test&content=hello
  2. multipart/form-data : form 表单提交的数据格式(在 form 标签中加上
    enctyped="multipart/form-data" 通常用于提交图片/文件. body 格式形如:

    • Content-Type:multipart/form-data; boundary=----
      WebKitFormBoundaryrGKCBY7qhFd3TrwA

      ------WebKitFormBoundaryrGKCBY7qhFd3TrwA
      Content-Disposition: form-data; name=“text”

      title
      ------WebKitFormBoundaryrGKCBY7qhFd3TrwA
      Content-Disposition: form-data; name=“file”; filename=“chrome.png”
      Content-Type: image/png

      PNG … content of chrome.png …
      ------WebKitFormBoundaryrGKCBY7qhFd3Trw

  3. application/json : 数据为 json 格式. body 格式形如

    • {“username”:“123456789”,“password”:“xxxx”,“code”:“jw7l”,“uuid”:“d110a05ccde64b16a861fa2bddfdcd15”}
    • 第三种最常见请求中的 body 的格式,json (1.自定义应用层协议 2.js 的对象)

关于 Content-Length 的补充:

HTTP 也是基于 TCP 的协议
TCP 是一个面向字节流的协议,粘包问题 => 合理设计应用层协议,来明确包和包之间的边界!!

这两个在 HTTP 中都有体现:

  1. 使用分隔符
    • 如果当前有若干个 GET 请求到了 TCP 接收缓冲区中了…
      应用程序读取请求的时候,就以空行为分隔符
  2. 使用长度
    • 如果当前是有若干个 POST 请求,到了TCP缓冲区了
      这个时候,空行后面还有 body,当应用程序读到空行之后,就需要按照 Content-Length 表明的长度,继续读若干长度的数据

3.3、User-Agent (简称 UA)

表示的是,当前用户是在拿一个啥样的东西来上网

在这里插入图片描述

主要是 操作系统信息+浏览器信息

上古时期,浏览器处在一个飞速进步的状态,最开始的浏览器,只能显示文本
再后来,能够显示图片了
再后来,能够显示各种复杂的样式了,再后来,能够加载 js 实现交互了
再后来,能够支持各种多媒体了(播放视频啥的

以前的时候,由于浏览器发展很快,导致市场被严重割裂了

一部分用户,用的是比较老的浏览器(只能显示文本)
—部分用户,用的是比较新的浏览器(能够支持js )

这个时候就给网站开发人员带来了挑战
为了解决这个问题,聪明的程序猿就想到了,让浏览器发送的请求中,来个自报家门
服务器就可以根据浏览器中的这个自报家门的信息,就可以做出区分了

在2022年的今天,主流浏览器的功能已经差别很小 (十年前,浏览器兼容性,还是前端开发要考虑的大问题),UA 这个字段起到的作用就已经不那么大了
但是随着当下移动互联网的到来,UA 现在又有了新的使命:用来区分是 PC 端 还是 手机端
最大的区别,就是屏幕的尺寸和比例!!!
屏幕尺寸是远远小于PC端 (一般手机端的网页,就得把按钮之类的设计的大点),屏幕比例 PC 都是宽屏,手机都是窄屏,比例不同就导致页面布局就得不同
因此,服务器就可以根据 UA 来区分当前是手机还是电脑,如果是手机就返回手机版的网页,如果是电脑就返回电脑版的网页

User-Agent 之所以是这个样子是因为历史遗留问题,可以参考
User-Agent 的故事: http://www.nowamagic.net/librarys/veda/detail/2576


3.4、Referer

  • 表示了当前的页面,是从哪个页面,跳转过来的
  • Referer 不是一定有的,如果你是通过浏览器地址栏直接输入地址,或者直接点收藏夹,这个时候是没 referer

Referer: https://gitee.com/login

Referer 这个东西也是一个非常有用的字段,广告系统,按点击来计费!!

在这里插入图片描述

只要用户在搜索结果中,点击了,这个点击就会触发计费!! (广告主,就得给搜狗钱!!) CPC 广告(按点击计费)

既然是按照点击计费,一天/一个月这个广告一共被点了多少次? 得有一个明确的统计!!!

ROI投入产出比,这个统计,是搜狗统计,还是广告主统计?? 实际上就是双方都统计

搜狗统计:每次点击请求,其实都会先访问搜狗的服务器,再跳转到广告主的页面

在这里插入图片描述

一点击,就把这个请求发给了搜狗的计费服务器 (bill server),搜狗就可以按照这个服务器上收到的数据来进行统计

广告主统计:广告主的网站上,也是能记录一些日志的

一个广告主,可能在多个平台投广告
广告主就可以 通过 Referer 来区分当前的请求是哪个广告平台导入过来的流量

在这里插入图片描述

是否可能有一种操作,把 HTTP 请求中的 Referer 给篡改了?本来是搜狗,给改成别的了
这种可能性是完全有的,而且一度非常猖獗!
这个事情,谁有能力干? 谁有动机干? => 运营商

运营商也有自己的广告平台。

网络基础设施(路由器交换机) 都是运营商提供的,网络流量经过了人家的设备,人家的设备就可以对你的请求进行抓包,并且进行修改操作

这个情况在2015年之前,是非常普遍的。这里,官司该打要打,但是也要通过技术手段进行反制:HTTPS
2015年之前,百度,搜狗 等广告平台,都是用 HTTP 协议的,(当年网络上的 HTTPS 非常少),于是这些大的互联网公司纷纷开始升级,升级到了 HTTPS


3.5、Cookie

浏览器,为了安全,默认情况下是不能让页面的 js 访问到用户电脑上的文件系统的
假设某个网页上,包含恶意代码,不小心一点,就可能触发这个恶意代码,把你电脑上的一些文件全给删了!!!

但是这样的安全限制,也带来了一些麻烦,有时候,确实又需要让页面这里持久化存储一些数据,方便后续访问网站

其中,最典型的,就是需要存储用户当前的身份信息
当用户在登录页面完成身份认证之后,此时服务器就会给浏览器返回一个用户的身份信息,浏览器把这个信息就保存到了一个特定的位置上,后续再访问同一个网站的其他页面的时候,浏览器再自动的带上这个身份信息,服务器就能识别了

因此当前就是采取这样的策略!!!
虽然不能让页面的 js 访问你的整个磁盘数据,但是可以单独给浏览器分配一个小黑屋,js 代码就可以在这个小黑屋里随便折腾,这里的折腾,就不会影响到你磁盘上的其他的学习资料

这里的小黑屋,有多种不同的形式。
其中 Cookie 是一个比较古老,也比较经典的形式,现代浏览器也支持一些其他的本地存储的方案

Cookie 就是浏览器给页面提供的一种能够持久化存储数据的机制 ,持久化指的就是,数据不会因为程序重启或者主机重启 而丢失 (写到磁盘里)

Cookie具体的组织形式:

  1. 按照域名来组织,针对每个域名,分别分配一个小房间。我访问搜狗,浏览器就会给 sogou 这个域名记录一组 cookie,我访问码云,浏览器也就会给码云也记录一组 cookie
  2. 一个小房间里面,又会按照键值对的方式来组织数据

在这里插入图片描述

Cookie 数据从哪里来的:其实是服务器返回给客户端的

包含了一组这样的 header,就是服务器完成身份认证之后,就给客户端返回了一些具体的信息,信息就是通过 Set-Cookie 这样的响应报头来表示的

在这里插入图片描述

Cookie 里面保存身份信息,这件事,就类似去医院看病

  • 去医院,第一件事,要先挂号
    在挂号处,除了要交钱之外,人家还会给你一个就诊卡,给你就诊卡的时候人家工作人员会问你,要你的具体信息(姓名,身份证号码,电话号码…

  • 后续看病的过程中,这个就诊卡就起到了至关重要的作用
    先来到了儿科诊室,医生在看病之前,要先刷一下我的就诊卡,刷卡就是在获取到我的身份信息,身份信息里除了基本信息之外,还有以往病例

  • 经过了一番诊断,医生给我开了一些单子:
    去检验科,抽血化验,做血常规。还是拿着我的就诊卡一刷,这一刷就获取到了我的基本信息,和刚才医生给我开的具体的化验内容去放射科

    排个 X 光片。也是拿着我的就诊卡—刷,就知道要拍一个啥样的片子…

  • 在上述过程中,我手里的就诊卡就是 cookie !!!
    虽然就诊卡上面可以存储一些信息,但是保存的数据量是有限的
    真正保存我的这些信息,并不是这个卡,而是放到了医院的服务器上,而卡上,只需要存储我的一个身份标识 (存一个用户 id )

这些关键信息,存储在服务器上,管这个东西称为 “session”,会话

服务器这里管理着很多很多的 session
每个 session 里面都存储了用户的关键信息 (基本信息,要做的检查,以往病例…),每个 session 也有一个 sessionld (会话的标识)

就诊卡上其实存储的是这个会话的 id

在这里插入图片描述

这个东西看起来就很像是一个 sessionld
服务器就可以根据这个数据,来找到用户对应的会话,进一步获取到用户的详细情况
cookie 这里存的键值对,也是和 query string 类似,也都是程序猿自定义的,外人不知道,看不懂

总结:

  • Cookie 是浏览器提供的一个持久化存储数据的机制
  • Cookie 的最重要的应用场景,就是存储会话 id,进一步的让访问服务器的后续页面的时候,能够带上这个 id,从而让服务器能够知道当前的用户信息 (服务器上保存用户信息这样的机制就称为 Session 会话)
  • Cookie 能不能用来存别的信息?? 当然也是阔以的!!! 具体想存啥,就存啥,都是程序猿自定义的!!!

关于 Session 会话的理解:QQ 的消息列表,就相当于 “会话列表”,这里的聊天记录,就相当于用户的详细信息了


4、正文 body

正文中的内容格式非常灵活,取决于 header 中的 Content-Type
下面可以通过抓包来观察这几种情况:

  1. application/x-www-form-urlencoded 和 query string 一样,键值对结构,键值对之间使用 & 分隔,键和值之间使用 = 分割,并且要进行 url encode

    • 抓取码云上传头像请求

      avatar=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAAPgAAAD4CAYAAADB0Ss
      LAAAg…

  2. multipart/form-data 上传文件

    • 抓取教务系统的 “上传简历” 功能

      ------WebKitFormBoundary8d5Rp4eJgrUSS3wT

      Content-Disposition: form-data; name=“file”; filename=“李星亚 Java开发工程师.pdf”
      Content-Type: application/pdf

      %PDF-1.7

      1 0 obj
      <</Names <</Dests 4 0 R>> /Outlines 5 0 R /Pages 2 0 R /Type /Catalog>>
      endobj
      3 0 obj
      <</Author ( N v~N•) /Comments () /Company () /CreationDate
      (D:20201122145133+06’51’) /Creator ( W P S e [W) /Keywords () /ModDate
      (D:20201122145133+06’51’) /Producer () /SourceModified (D:20201122145133+06’51’)
      /Subject () /Title () /Trapped /False>>
      endobj
      13 0 obj
      <</AIS false /BM /Normal /CA 1 /Type /ExtGState /ca 1>>
      endobj

  3. application/json{} 构成的键值对,键值对之间使用逗号分割,键和值之间使用 : 分割

    • 抓取教务系统的登陆页面

      {“username”:“123456789”,“password”:“xxxx”,“code”:“u58u”,“uuid”:“9bd8e09ea27b48cdacc6a6bc41d9f462”}

抓包是一个很有用的技能

  • 理解 HTTP
  • 调试一个 web 程序
  • 实现一个爬虫
    • 自己写一个 HTTP 客户端,来模拟人的操作,来自动从网站上获取到一些内容
      任何一个编程语言,只要能操作网络,都可以写爬虫,使用 Java 写爬虫,也是很常见的操作
    • 每个网站会提供一个 robot.txt 这样的文件,这个文件告诉你说那些资源是可以合法的进行爬取,理论上来说,只要你爬取了这个人家给的白名单之外的内容,都算非法行为

四、HTTP 响应

1、状态码 (status code)

表示这次请求是成功还是失败,以及失败的原因是什么

HTTP提供的状态码,有很多:

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

404 Not Found 要访问的资源不存在

sogou.com/1.html:

在这里插入图片描述

bilibili/1.html:

在这里插入图片描述

403 Forbidden 虽然资源有,但是你没有权限使用(丑拒)

HTTP/1.1 403 Forbidden

这个情况,你去外面的网站上抓包,很难遇到… 但是如果后面自己写网站后台,这个就很容易出现
例如,尝试使用 GET 来访问人家的服务器,但是可能人家只支持 POST,于是就会返回 405

500 Internal Server Error 服务器自己出问题了,意味着出现 bug,外面的服务器上看到这种情况的概率也是比较低的,但是咱们后面自己写代码,也是很容易出现这个情况的

504 Gateway Timeout 服务器太繁忙了

302 Move temporarily 重定向

在登录过程中,非常典型的情况

这个词在计算机的很多场景中都会涉及到,不仅仅是 HTTP
但是虽然在不同场景中细节上有差异,但是表示的核心含义,都是呼叫转移
呼叫转移:中国移动,运营商这里可以办理的一个业务,有人拨打我的旧号码,就会自动的转接到我的新号码上

HTTP/1.1 302 Found
Location: https://gitee.com/xxxxxxxxx/kodi-source
Location 就描述了接下来要跳转到哪里!!
在重定向响应中,一般都是需要 Location 属性的

HTTP 状态码的种类:

在这里插入图片描述

2 开头,都属于成功 —— 200

3 开头,都属于重定向 —— 301 302

4 开头,都属于客户端出现错误了 —— 404 403

5 开头,都属于服务器出现错误了 —— 500 504

1 和 6 开头的状态码非常少,也很少见

在这些状态码中,其实还有一个特别的,418
418 虽然在搜狗百科上没有,但是确实存在于 HTTP 标准文档中,
描述:l am a teapot 俺是一个茶壶
是一个彩蛋 (程序猿的幽默)

但是实际开发中,谨慎搞彩蛋,一个典型的负面案例:
前端领域有一个 ant design 开源组件 (阿里搞的),之前这个还是非常火的,很多人都在用
这个作者就搞了一个彩蛋,在圣诞节这天会触发这个彩蛋,
使用了 a d 的组件,就会在圣诞节这天,上面出现一个 “小云彩” 这样的小 logo
客户表示,这个按钮为什么被狗啃了一半


猜你喜欢

转载自blog.csdn.net/qq_56884023/article/details/125008066