【网络原理】万字详解 HTTP 协议
🥰🥰🥰来都来了,不妨点个关注叭!
👉博客主页:欢迎各位大佬!👈
文章目录
- 1. HTTP 前置知识
- 1.1 HTTP 是什么
- 1.2 HTPP 协议应用场景
- 1.3 HTTP 协议工作过程
- 2. HTTP 协议格式
- 2.1 fiddler 抓包工具查看 HTTP 报文格式
- 2.2 HTTP 报文格式
- 2.2.1 HTTP 请求报文结构
- 💚 请求行:方法+URL+版本号
- 💚 请求报头 header
- 1)Host
- 2)Content-Type / Content-Length
- 3)User-Agent (简称UA)
- 4)Referer
- 5)🔥Cookie
- 💚 请求正文 body
- 2.2.2 HTTP 响应报文结构
- 💚 响应行:版本号+状态码+状态码描述
- 💚 响应报头 header
- 💚 响应正文 body
- 3. 如何构造 HTTP 请求
- 3.1 直接通过浏览器地址栏输入一个 url
- 3.2 html 一些特殊标签也会触发 GET 请求
- 3.3 form 表单可以发 GET 和 POST 请求
- 3.4 ajax
- 3.5 构造 HTTP 请求工具 —— Postman
1. HTTP 前置知识
1.1 HTTP 是什么
HTTP 是一个使用非常广泛的应用层协议,HTTP 请求发送出去,就需要从应用层到物理层,层层封装,接收方收到后,再从物理层到应用层,层层分用,最终才能够完成传输
应用层协议,经常需要进行"自定义协议"的,但是,很多时候也不一定非得从零开始设定,以可以基于一些已经有的设计好的协议,在这个基础上制定
1.2 HTPP 协议应用场景
HTTP 应用的非常广,主要原因就是 HTTP 可制定性非常强!
Q:既然说 HTTP 应用得非常广,哪些场景下使用了的呢?
A:只要你在上网,就在使用!!!
比如说,浏览器打开一个网页,手机 app 从网络上加载一份数据等等~
1.3 HTTP 协议工作过程
HTTP 是"一问一答"这种形式的协议,即一个请求一个响应
2. HTTP 协议格式
2.1 fiddler 抓包工具查看 HTTP 报文格式
学习 HTTP 协议,最主要的就是认识 HTTP 的报文协议格式,而要想认识报文格式,需要借助一些外部的工具,来把 HTTP 协议来显示出来
这个外部工具,即抓包工具,本质上相当于一个"代理",借助这样的代理,可以看到网络传输的具体数据
当然,抓包工具有很多,本期内容使用的是 fiddler,专注与 HTTP,使用起来也比较简单~
fidder 安装:可以去官网直接安装
fidder 使用:左侧是抓到包的列表,列表中的内容,是在持续滚动的;点击要关注的包,右侧会显示详情,右上是请求,右下是响应
fiddler 小技巧:找自己发的包,先看颜色,黑色的包,响应是普通数据,蓝色的包,响应是 HTML;再看域名;还可以看看响应的数据长度,一般是找长度比较长的
fiddler 可能遇到的问题:
1)fiddler 作为一个代理,可能和电脑上其它的代理冲突
2) 没有勾选 HTTPS,没有安装根证书,无法解析 HTTPS 数据,这样可能抓到的东西就会很少
借助 fiddler 工具,来看一看~
借助上述抓包工具,就可以看到 HTTP 协议请求和响应的详细内容:
一个 HTTP 请求包含4个部分
- 首行
- 报头 header
- 空行
- 正文 body
一个 HTTP 响应包含4个部分
- 首行
- 报头 header
- 空行
- 正文 body
其中 HTTP 本身是文本格式,如果看到响应乱码,则是经过压缩,成了二进制文件,因为带宽比较贵,压缩能够减少网络传输的数据量,节省带宽,把数据压缩,本质上是用 CPU 资源换带宽资源,因此,很多网站会对数据进行压缩
接下来进一步研究这个格式的细节信息!
2.2 HTTP 报文格式
2.2.1 HTTP 请求报文结构
💚 请求行:方法+URL+版本号
【1.对于方法解释说明】
抓几次包,小伙伴们不难发现,怎么请求的方法只有 GET 呢~ 还有其它的嘛
一般请求都是 GET,当然也有 POST 的,如以下场景:
1) 登录的时候
2)上传文件的时候
最常的就是 GET 和 POST 啦
HTTP 方法描述了这个 HTTP 请求想干什么,HTTP协议有很多种方法,不同的方法,表示不同的语义,这里列举一些方法,如下:
方法 | 说明 | 支持的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 和 POST 的区别:
GET 和 POST 表示的是不同的语义,但是,实际上,也并非需要严格遵守,HTTP 方法的语义,只是一种建议,小伙伴们在使用的时候,也不一定非得遵守(注意建议~)对于 body 有没有的问题,GET 一般是没有 body 的,也可能有 body,非常少见,POST 一般有 body,当然,也可以没有 body,但比较少见!
本质上没有区别,但是在使用习惯上有区别
- GET 习惯上用来表示’'获取一个数据",POST 则习惯用来表示 “提交一个数据”
- GET 一般没有 body,需要携带数据则放到 URL 中,POST 一般有 body
- GET 请求通常会设计成幂等的,POST 则无要求
- GET 可缓存的(前提是幂等),POST 则不能
- GET 请求可以被浏览器收藏,POST 则不能
【2.对于 URL 解释说明】
URL 即 唯一资源定位符,描述了网络上唯一的一个资源
(这个概念严格的说,并非是 HTTP 里的概念,很多协议都会用到 URL,比如 MySQL 中的 JDBC,就用到过 URL)
URL 的结构如下:协议名 + 域名 + 端口号(可省略)+ 带层次结构的路径 + query string 参数(查询字符串)
补充:端口号省略并不是没有,而是浏览器会自动加上默认的端口号,对于 HTTP来说,默认端口号是80,对于 HTTPS来说,默认端口号是443
举一个栗子,更好的理解 URL ,如下:
小万特别喜欢吃煎饼果子,以后小万不做程序猿啦,在学校食堂开了一家煎饼果子店,如何找到小万呢?
URL 结构,是不是一目了然啦~ 同时,我们也会在计算机网络中,听到 URI 这个词,这里作出解释:
【URI 和 URL 的区别】:
- URI 是唯一资源标识符,可以唯一标识一个资源;
- URL 是唯一资源定位符,可以提供该资源的路径;
联系:URL 是一种具体的URI,URL 不仅可以标识一个资源,还能提供该资源的路径
举例:URI 的作用就像身份证一样,可以唯一标识一个人,而 URL 的作用则像家庭住址,不仅可以唯一标识一个人,还提供了定位该资源的信息
【3.对于版本号解释说明】
HTTP 版本有 HTTP/1.0、HTTP/1.1、HTTP/2.0、HTTP/3.0
最常见的版本号是 HTTP/1.1,最主流的版本~
HTTP 1.0 默认短连接,HTTP 1.1 默认长连接,HTTP 2.0 采用多路复用
(这里作简单了解)
💚 请求报头 header
请求行,占一行,下面的信息就是请求头,以空行为分隔~ 是键值对结构,每个键值对占一行,键和值之间,使用冒号空格分隔,这里的键值对可以有 N 行,会用空行作为结束标记,空行就类似于链表的 null
header 中的键值对,大部分都是 HTTP 协议规定的,当然,这里也可以添加自定义键值对,所以,可制定性强~
下面介绍一下,请求行里面部分属性的内容~
1)Host
Host 这个属性描述了浏览器这个请求要访问的服务器是谁,这里写的不仅仅是地址,也可以是端口号~
有的小伙伴就会问了,在 URL 中已经写了当前要访问的服务器是谁,为什么在请求头这里的 Host 要再写一次呢?
这是因为,大多数情况下,Host 中的值和 URL 中的域名是一致的(言外之意,还有不一致的情况~)比如当前我们访问的服务器不是直接访问,而是通过"代理"来访问,此时 Host 和 URL 可能就不一致了,Host 是最终目标,URL 中的是当前目标,可以一致,可以不一致滴!
2)Content-Type / Content-Length
- Content-Type :描述了 body 的数据格式
- Content-Length :描述了 body 的长度(字节)
这两个属性,都是跟着 body 走的,GET 请求一般没有 正文body,所以上述的图片中,没有看到这两个属性,而 POST 一般有 body,因此,如果有 body 的话,会有这两个属性
可以看到,body 的长度是 707 字节,类型是 application/json 数据的格式,描述数据是按照 json 格式来组织的~
json 格式是用 { } 来表示的,里面包含若干键值对,键值对之间使用,分割;键和值使用:分割,格式如下:
{"username":"xxxx","password":"xxxx","status": 0
}
在进行前后端交互(浏览器和 HTTP 服务器),json 是常用的格式~
Content-Type 还会有其它的格式,如:
application/x-www-form-urlencoded —— form表单提交数据的时候,会生成这种格式的 body,此时,body 的格式就是和 query string 是一样的,username:xxxx&password:xxxx&status: 0
作为请求,Content-Type 就是 json 和 application/x-www-form-urlencoded ,这两种写法比较多
作为响应,Content-Type 有 text/html、text/css、application/javascript、appliccation/json、image/jpg、image/png…
有了上述的格式描述,浏览器/HTTP服务器,才能够认识到当前的 body,并正确的进行解析~
Q:为什么找不到 text/css、application/javascript 这种格式?
A:浏览器缓存问题! 浏览器中直接按 F5 刷新,按 Ctrl + F5,是强制刷新,会把缓存的数据页重新加载,比如 css,js,图片,字体等,每次访问一个页面,都需要把依赖的这些资也加载到浏览器这边,加载这些资源,都需要有一定的网络开销,由于上述 css,js 都是固定的,很少变化,就可以把这些资源在加载一遍之后,保存在浏览器所在机器的本地硬盘上,此时后续再访问服务器,访问页面,就只加载 html 即可,其它这些资源就不必加载了,此时就可以认为,本地主机的硬盘,就是远端服务器的一个"缓存"
3)User-Agent (简称UA)
User-Agent:描述用户使用的客户端是什么样的,主要描述了浏览器是什么版本,系统是什么版本
(细心的小伙伴观察到这里是 win10,但其实笔者用的是 win11,猜测可能是 win10 和 win11 是一样的内核版本~)
- Q:为什么要有 UA 呢?
- A:早期电脑硬件配置比较差,当时浏览器上网功能比较原始,最早浏览器只能显示文本,再后来可以显示图片,接着又可以显示视频/音频,再后来可以支持 js,再后来可以支持 flash,再发展,又有了新的很多很多特性~ 这个就导致,同一时期,浏览器的种类繁多,功能参差不齐,对于网站开发来说,难度就大大提升了,于是,就发明了 User-Agent,就可以在请求中,告诉网站服务器,当前我们当前上网的设备是啥,此时,服务器就可以根据客户端的种类,返回不同的页面~
不过,随着时间的推移,浏览器过了快速发展的阶段了,现在的浏览器,之间的区别已经越来越小了,此时,UA 这个属性存在的价值,就大打折扣了~ UA 现在一个重要的用途,就是要区分用户是手机/PC/平板
虽然 UA 能够做到这一点,但是实际上,现在还有更好的解决方案,CSS3 里提供了 “媒体查询” 功能,可以根据浏览器窗口大小,来设置不同样式,这种页面开发方式,称为 “响应式布局”~
4)Referer
Referer:描述了当前这个页面,从哪个页面跳转过来的~
- 如果直接在地址栏输入 url,此时请求中没有 referer (如果点收藏夹里面的,效果也是一样的,没有 referer)
- 在搜索结果页中,就可以看到 referer 就是笔者的 gitee 主页 ,这个是从笔者主页跳转来的~
- Q:这个 referer 有什么用呢!
- A:用处不是多,但是很关键~ 比如在广告方面
比如我在这个广告平台上一点广告,就跳转到了广告主的页面,此时,广告主服务器这个访问,就会带有这个广告平台的 referer,广告主可能会通过多个平台投放广告,因此,就可以通过 referer 来区分,看当前这次访问是哪个平台导入的流量~
但是有没有一种可能,广告主这里收到了请求 referer 被篡改了~
明明是通过这个平台跳转过去的,应该带这个广告平台的 referer,但是被改成了别的广告平台
答案是肯定有可能的,比如运营商(中国移动、中国联通、中国电信),它们是有能力的,网络通信设备是运营商提供的,我这边的访问广告主的网站,我的请求、我的数据、都是通过运营商的交换机/路由器转发的,只要运营商在它的设备上部署一个小小的抓包程序,识别特定的包,就可以做出修改,当然,也是有动机的,因为运营商也有自己的广告平台!
因此,需要通过技术手段,进行反制,让运用商篡改不了,就可以啦!
办法就是,加密,HTTPS!现在互联网绝大部分网站都是 HTTPS 的,有效保护数据不被篡改,当然,任何加密手段都不是万无一失,如果破解成本超出了数据本身价值,这个时候就是安全的!(这里 HTTPS 闪亮登场,下期讲解 HTTPS ,敬请期待~)
5)🔥Cookie
Cookie : 是客户端保存用户信息的一种机制~ Cookie 的值,也是键值对,键值对之间使用;分割,键和值之间使用 = 分割,这里 Cookie 的键值对具体是什么含义,我也不知道,只有这个网站的开发者知道,这里的键值对都是程序员自定义的数据,不同的网站就有不同的键值对,也就有了不同的含义和用途~
我们当前在 HTTP 中遇到很多键值对,这里作一下总结:
- url 中的 query string
- header 部分,每一行是一个键值对
- body 部分,如果 Content-Type 为 x-www-form-urlencoded 或者 json,body 的内容也是键值对
- Cookie 里面存储的数据还是键值对
这些键值对,都是允许用户自定义的,这些自定义的键值对,都是 HTTP 留给程序员进行扩展的地方~(这就是为什么 HTTP 流传这么广泛,这个场景这样定义,那个场景那样定义一下)
Cookie 的本质是浏览器在本地存储用户自定义数据的一种关键机制
如何理解这句话呢?结合这张图进行讲解与理解~
既然浏览器自身也需要存储数据,那么怎么存呢?
1)直接存储到硬盘文件上,是不是就行了? —— 这个事情是万万不行的,如果允许网页能够操作你电脑的文件系统,那么一旦你不小心点到了一个奇怪的网站,很可能网站就做一些恶意的事情,比如把你硬盘上的学习资料都一锅端了~ 所以,为了保证用户上网能够比较安全,浏览器会做出限制,禁止网页能够直接访问硬盘~
2)浏览器虽然禁止直接访问硬盘,但是浏览器提供了 Cookie 机制,允许网页往浏览器这边存储一些自定义的键值对,这些数据通过浏览器提供 api,写入特定的文件中
由于网页有很多,比如我访问百度,是需要存储一些数据,我访问搜狗,也需要存一些数据
针对这种情况,做法是分开存储的,每个网站都存储自己的 Cookie(cookie 是按照域名维度进行存储的)
即同一网站(百度主页和百度搜索结果页…)共享同一份 Cookie
不同网站(百度、淘宝等)则是各自有各自的 Cookie
从 3 个方面,彻底弄清 Cookie!
- Cookie 从哪里来
从服务器来,当我们的浏览器访问服务器的时候,服务器就会在 HTTP 响应中,通过 Set-Cookie字段,把 Cookie 的键值对,返回给浏览器,浏览器收到这个数据,就会在本地存储 - Cookie 到哪里去
会在下次请求的时候,将 Cookie 带给服务器,Cookie 在浏览器这边,只能算是"暂存",真正让这个数据发挥作用的还是得由服务器来使用 - Cookie 的作用
是浏览器本地存储数据的机制,存的数据不一定非得是角色,任何想存的数据都行,前提是必须得是字符串,由于Cookie 存储空间有限,一般也不会用 Cookie 存太大的,最典型应用就是保存用户的登录状态
1)Cookie 在哪儿看?
点击浏览器这里的小锁,可以看到里面有 Cookie 和站点数据,如下:
点进去,可以看到如下:
从这张图,我们也可以知道,以域名为维度区分的~
点击一个进入查看~
可以看到,Cookie 存储的内容有:
- 名称
- 内容
- 域
- 路径
- 发送
- 已创建
- 到期
2)Cookie 最典型的应用 —— 存储用户的身份信息(即用户登录之后的身份)
由于客户端有很多,每个客户端提供的服务可能还不太一样,比如说,普通用户和管理员,他们权限就不一样!因此,服务器就可以通过 Cookie 来进行区分,比如客户端在登录的时候,服务器就识别好客户端的角色,把角色信息返回给浏览器,在 Cookie 中保存,后续客户端访问的时候,带着这个 Cookie 就可以了,此时,服务器就直接知道这个客户端是干嘛的了~
其实在生活中,这就像买东西的发票,有了发票,就有了一份售后保证,可以凭借发票与商家沟通售后问题~
再具体举一个生活中的栗子~ 去医院看病的流程(当然,希望小伙伴们健健康康,平平安安~)
1)第一步:去医院先是挂号,挂号的同时,医院会给你一张就诊卡,办理就诊卡需要你的身份证,电话之类的个人信息
2)第二步:挂号完成,可以去诊室看病, 医生第一句话就是刷一下就诊卡,这个就诊卡就包括了身份信息,如你的姓名、身份证、年龄、性别…还有以往的病例,当前开出的额诊断,当前开的药…
3)接着来到检验科,刷一下就诊卡,检验科的医生会根据就诊卡来确定具体做什么检查
4)来到影像科,刷一下就诊卡,同样的,影像科的医生会根据就诊卡来确定具体做什么检查
此时,这个就诊卡就是 Cookie~
💚 请求正文 body
正文中的内容格式和 header 中的 Content-Type 密切相关,上面也罗列了 3 种情况(这里不作详细介绍)
1)application/x-www-form-urlencoded
2)multipart/form-data
3)application/json
2.2.2 HTTP 响应报文结构
💚 响应行:版本号+状态码+状态码描述
1)版本号:和请求中相同
2)状态码:数字,通过这个数字来表示这次请求执行成功还是失败,如果是失败,给出失败的原因
3)状态码描述:通过一个或者一组单词,描述这个状态码的含义
状态码有很多,如下:
(ps:图片来自搜狗百科!)
虽然状态码种类繁多,但是常用的就那几个!下面具体介绍常用的状态码~
- 200 OK 表示请求成功
- 404 Not Found 表示要访问的资源不存在
- 403 Forbidden 表示访问被拒绝(没有权限)
- 500 Internal Server Error 表示服务器内部错误(比如你的服务器出 bug 的,抛异常没有 catch 到,就会出现 500)
- 504 Gateway Timeout 表示服务器访问超时(浏览器给服务器发请求,服务器要返回响应,结果服务器迟迟没有响应)
- 302 Move temporarily 表示临时重定向(临时,代表下次要不要继续重定向,是不确定的)
- 301 Moved Permanently 表示永久重定向(以后都重定向)
重定向:就是访问旧的地址被自动引导到新的地址上
了解上述常用的状态码即可,其它的去查就好啦,尽管状态码很多,但是可以分为以下这五类:
类别 | 原因短语 | |
---|---|---|
1xx | informational(信息性状态码) | 接收的请求正在处理 |
2xx | Success (成功状态码) | 请求正常处理完毕 |
3xx | Redirection(重定向状态码) | 需要进行附加操作以完成请求 |
4xx | Client Error(客户端错误状态码) | 服务器无法处理请求 |
5xx | Server Error (服务器错误状态码) | 服务器处理请求出错 |
💚 响应报头 header
响应报头的基本格式和请求报头的格式基本一致,类似于 Content-Type,Content-Length 等属性含义和请求中的含义一致
响应报头 Content-Type 常见有以下几种:
- text/html : body 数据格式是 HTML
- text/css : body 数据格式是 CSS
- application/javascript : body 数据格式是 JavaScript
- application/json : body 数据格式是 JSON
💚 响应正文 body
根据响应报头 Content-Type 的属性决定~ 上面也罗列了 4 种情况(这里不作详细介绍)
- text/html
- application/javascript
- application/javascript
- application/json
以上就是关于 HTTP 协议,整体格式的介绍啦~
3. 如何构造 HTTP 请求
3.1 直接通过浏览器地址栏输入一个 url
这样直接构造出一个 get 请求~
3.2 html 一些特殊标签也会触发 GET 请求
- link
- script
- img
- a
比如有一个页面,有一个 img 标签,此时,当页面加载好之后,浏览器就会根据 img 标签的 src 属性,给服务器发起一个 GET 请求,来获取到图片的内容~(当然,你访问的资源得是网络资源,如果是本地资源,自然不会发起 GET 请求)
3.3 form 表单可以发 GET 和 POST 请求
1)form 发送 GET 请求,如下:
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8" /><title>form 表单</title>
</head>
<body><form action="http://www.baidu.com/myPath" method="GET"><input type="text" name="aaa"><input type="text" name="bbb"><input type="submit" value="提交"></form>
</body>
</html>
form 其中的属性解释:
- action : 表示要访问的 URL
- method : HTTP 请求的方法
- input 的 name :对应 query string 的 key
- input 的 内容 : query string 的 value
对应关系参考下图(其实不难理解的,需要用心去看~)
2)form 发送 POST 请求,如下:
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8" /><title>form 表单</title>
</head>
<body><form action="http://www.baidu.com/myPath" method="POST"><input type="text" name="aaa"><input type="text" name="bbb"><input type="submit" value="提交"></form>
</body>
</html>
对应参考如下(POST 请求 input 内容在 body 里,GET 请求 input 内容在 query stirng 里)
form 表单只支持 get 和 post,其它 put、delete 等 http 方法,form 表单就无能为力了~ 而且使用 form 的话,版本号固定是 HTTP/1.1
3.4 ajax
ajax 现在是最主流的前后端交互方式~
ajax 全称:Asynchronous Javascript And XML,是 2005 年提出的一种 JavaScript 给服务器发送 HTTP 请求的方式~
1)Asynchronous
synchronized 是同步,Asynchronous 加个 a 前缀,是异步~
在计算机中,一个术语,很可能存在多种含义,需要结合上下文
- 同步和互斥(加锁的场景),把同步理解为互斥可能更好一点,加了 synchronized 这个锁之后,加锁之后就变成互斥的了
- 同步和异步(IO的场景),主要是网络上的 IO,比如这里的同步,可以理解成我来到饭馆,老板来个蛋炒饭,接下来我就一直在这个出餐口等着,一直等到老板把饭做好,我把饭端走,而异步,则是我找了个地方坐下来,玩手机,该干嘛干嘛,等饭做好了,老板直接给我端上来~ 异步,则是请求发起者不关心结果,而是由被请求的这一方面计算出结果后,把结果发送给发起者(就是看是否是自己取的啦)
2)xml
网络应用层,自定义协议,和 json 一起登场的~ 是一种自定义数据格式的方式,基于标签的形式,很多配置文件也会用到 xml,比如 pom.xml、web.xml 等(html 和 xml 都是由标签构成,html 来说,支持哪些标签,标签是什么含义,都是标准委员会规定的,xml 来说,标签都是自定义的~)
ajax 是前端和后端异步交互的方式~
- 那 ajax 如何写呢?
- js 给提供了原生了 ajax 的 api,这个 api 挺难用的,这里采用 jquery 中 提供的 ajax api
$:在 jquery 中是一个特殊的全局变量,jquery 中的各种 api 都是 $ 的方法,是变量名的一部分
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8" /><title>ajax</title><script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
</head>
<body><script>$.ajax ({url:"https://www.baidu.com",type:"GET", // 可以写 get、post、deletesuccess:{// 回调函数,写处理响应的代码}});</script>
</body>
</html>
回调函数:会在服务器返回一个正确的响应的时候,被浏览器自动执行,这个执行过程就是“异步”的
在我们页面中的 js,把请求发出去就不管了,就继续执行后续的代码,直到说,响应回来之后,浏览器就会把这个响应喂给我们的代码,浏览器调用上述这个回调函数,执行处理响应的逻辑~
还有哪些关于回调函数呢~
- 函数指针 ——> 回调函数
- 集合类,优先级队列,Comparable(compareTo),Comparator(compare) ——> 回调函数
- 多线程,重写 run 方法/ lambda 表达式 ——> 回调函数
- …
即回调函数不会立刻就调,等到合适得到机会再调~
相比之下,ajax 比 form 功能更灵活,更丰富,尽管 ajax 有很多优势,但是还存在一个很重要的问题!
看看这个代码,能否跑起来~ 直接报错,如下:
这个属于 ajax 的一个非常典型问题,跨域问题,假设现在运行的 ajax 代码页面的域名是 adc.com,但是 ajax 里的请求,访问的域名是 def.com,这两个域名不一致的话,哪怕服务器给你的响应数据,浏览器还是不能处理,还是要报错~ 就是为了防止 a 网站的页面请求 b 网站的数据,后面自己写了服务器,自己的页面请求自己的服务器,自然就不会涉及跨域了~ 而 form 则允许跨域
3.5 构造 HTTP 请求工具 —— Postman
不写代码,现成的工具也可以直接构造 HTTP 请求 —— Postman(这里就不展开讲解~在官网下载安装十分方便,操作简单)
💛💛💛本期内容回顾💛💛💛
✨✨✨本期内容到此结束啦~
相关文章:
【网络原理】万字详解 HTTP 协议
🥰🥰🥰来都来了,不妨点个关注叭! 👉博客主页:欢迎各位大佬!👈 文章目录 1. HTTP 前置知识1.1 HTTP 是什么1.2 HTPP 协议应用场景1.3 HTTP 协议工作过程 2. HTTP 协议格式2.1 fiddler…...
WIFI连接与通信
ESP32-S3 支持 2.4 GHz 的 Wi-Fi 4(802.11n)标准,提供高达 150 Mbps 的数据传输速率。它支持 STA(Station)模式、AP(Access Point)模式和 Wi-Fi 直连(Wi-Fi Direct)模式&…...
Elixir语言的数据库编程
Elixir语言的数据库编程 介绍 Elixir是一种基于Erlang虚拟机(BEAM)的函数式编程语言,特别适用于构建可扩展和可维护的系统。它结合了Erlang的卓越并发特性和Ruby的易用性,因此在Web开发和实时应用中越来越受到欢迎。伴随着Elixi…...
python中Mako用法
Mako 是一个轻量级的 Python 模板库,它以其高效的代码生成和灵活的表达能力著称,常用于 Web 开发和静态文件生成。以下是对 Mako 的核心 API介绍。 1. 安装 Mako 首先安装 Mako: pip install mako2. 基本用法 Mako 的核心在于 Template 类…...
SMS4J - 一个聚合各种短信API商的工具
众所周知,在我们日常的项目开发中,短信验证码发送是一个必不可少的环节。 特别是如今手机互联网时代,基本所有东西都跟手机强绑定,所有的安全验证都离不开验证码这一环节。 所以对于一个系统来说,发送短信验证码成为…...
BEVFusion论文阅读
1. 简介 融合激光雷达和相机的信息已经变成了3D目标检测的一个标准,当前的方法依赖于激光雷达传感器的点云作为查询,以利用图像空间的特征。然而,人们发现,这种基本假设使得当前的融合框架无法在发生 LiDAR 故障时做出任何预测&a…...
【总结盘点类】2024,一场关于海量数据治理以及合理建模的系列写作
目录 1.今年的创作路线 2.先说第一条线 2.1.由日志引出的海量文本数据存储和分析问题 2.2.监控以及监控的可视化 2.3.数据量级再往上走牵扯出了大数据 2.4.由大数据牵扯出的JAVA线程高级内容 3.第二条线,也是2025要继续的主线 1.今年的创作路线 今年的写作内…...
【25考研】考清华的软件工程专业的研究生需要准备什么?
清华软件复试竞争一样很激烈!建议同学认真复习! 关于项目的注意事项先来一些总结: 千万别照抄开源项目 开源项目是一个很好的参考,但直接搬过来就没啥意义啦。我们可以根据开源项目学习它的技术架构和关键点,然后结…...
网络编程-UDP套接字
文章目录 UDP/TCP协议简介两种协议的联系与区别Socket是什么 UDP的SocketAPIDatagramSocketDatagramPacket 使用UDP模拟通信服务器端客户端测试 完整测试代码 UDP/TCP协议简介 两种协议的联系与区别 TCP和UDP其实是传输层的两个协议的内容, 差别非常大, 对于我们的Java来说, …...
EXCEL的一些用法记录
按某个分隔符进行拆分多列 【数据】- 【分列】 多列调整成多行 复制 - 粘贴 - 选择【转置】 部分内容替换 SUBSTITUTE()函数 ,固定内容 加“”...
不使用 JS 纯 CSS 获取屏幕宽高
前言 在现代前端开发中,获取屏幕的宽度和高度通常依赖于 JavaScript。然而现代 CSS 也可以获取到屏幕的宽高,通过自定义属性(CSS Variables)和一些数学函数来实现这一目标。本文将详细解析如何使用 CSS 的 property 规则和一些数…...
Node.js 完全教程:从入门到精通
Node.js 完全教程:从入门到精通 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,允许开发者在服务器端使用 JavaScript。它的非阻塞 I/O 和事件驱动架构使得 Node.js 非常适合于构建高性能的网络应用。本文将详细介绍 Node.js 的安装、基本语…...
可替代CentOS 7的Linux操作系统选型
可替代CentOS 7的其他Linux操作系统选型 一、背景介绍二、主流操作系统调研2.1 企业级产品:Red Hat Enterprise Linux/CentOS Stream2.1.1 Red Hat Enterprise Linux2.1.2 CentOS Stream2.2 其他发行版:Debian/Ubuntu2.3 开源产品:AlmaLinux / RockyLinux2.3.1 AlmaLinux2.3…...
【ESP32】ESP32连接JY61P并通过WIFI发送给电脑
前言 手头上有个ESP32,发现有wifi功能,希望连接JY61P并通过WIFI把姿态数据发送给电脑 1.采用Arduino IDE编译器;需要安装ESP32的开发板管理器; 2.电脑接受数据是基于python的; 1. ESP32 连接手机WIFI #include <…...
【JSqlParser】Java使用JSqlParser解析SQL语句总结
简述 Java解析SQL语句有很多工具都可以做到,比如Mybatis、Druid、目前用来用去最全面的仍然是Jsqlparser,它是一个Github上的开源项目,JSqlParser是一个用于解析SQL语句的Java库,它可以帮助开发者分析和操作SQL语句的结构。无论是…...
TCP断开通信前的四次挥手(为啥不是三次?)
1.四次握手的过程 客户端A发送 FIN(终止连接请求) A:我要断开连接了(FIN)。A进入FIN_WAIT_1状态,表示请求断开,等待对方确认。 服务器B回复 ACK(确认断开请求,但还未准备…...
解决用 rm 报bash: /usr/bin/rm: Argument list too long错
但目录里面文件过多用 rm 报bash: /usr/bin/rm: Argument list too long错时怎么办: 看看以下操作记录 rootmcu:/# cd /tmp rootmcu:/tmp# rm -f /tmp/chunk* bash: /usr/bin/rm: Argument list too long rootmcu:/tmp# rm -rf /tmp/chunk* bash: /usr/bin/rm: Arg…...
AI News(1/21/2025):OpenAI 安全疏忽:ChatGPT漏洞引发DDoS风险/OpenAI 代理工具即将发布
1、OpenAI 的安全疏忽:ChatGPT API 漏洞引发DDoS风险 德国安全研究员 Benjamin Flesch 发现了一个严重的安全漏洞:攻击者可以通过向 ChatGPT API 发送一个 HTTP 请求,利用 ChatGPT 的爬虫对目标网站发起 DDoS 攻击。该漏洞源于 OpenAI 在处理…...
从零到上线:Node.js 项目的完整部署流程(包含 Docker 和 CICD)
从零到上线:Node.js 项目的完整部署流程(包含 Docker 和 CI/CD) 目录 项目初始化:构建一个简单的 Node.js 应用设置 Docker 环境:容器化你的应用配置 CI/CD:自动化构建与部署上线前的最后检查:…...
哈希桶(开散列)
文章目录 前言实现插入put方法实现get方法实现泛型类哈希桶 前言 哈希桶用来解决哈希冲突,牺牲空间换取时间。 通过数组和链表来实现哈希桶 public class Node{public int key;public int value;public Node next;public Node(int key,int value){this.keykey;this…...
DEBERTA:具有解耦注意力机制的解码增强型BERT
摘要 近年来,预训练神经语言模型的进展显著提升了许多自然语言处理(NLP)任务的性能。本文提出了一种新的模型架构DeBERTa(具有解耦注意力机制的解码增强型BERT),通过两种新技术改进了BERT和RoBERTa模型。第…...
WWW2025 多模态对话系统意图识别挑战赛方案总结
WWW2025 多模态对话系统意图识别挑战赛方案 代码实现:https://github.com/klayc-gzl/incent_internvl_2.5_8b 最终成绩: 大赛背景 互联网已成为提供客户服务的主要沟通渠道。网络客户服务面临的一个关键挑战是服务对话中多模态意图的高效识别。通过利…...
渗透测试--攻击常见的Web应用
本文章咱主要讨论,常见Web应用的攻击手法,其中并不完全,因为Web应用是在太多无法囊括全部,但其中的手法思想却值得我们借鉴,所以俺在此做了记录,希望对大家有帮助!主要有以下内容: 1…...
w173疫苗发布和接种预约系统
🙊作者简介:多年一线开发工作经验,原创团队,分享技术代码帮助学生学习,独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取,记得注明来意哦~🌹赠送计算机毕业设计600个选题excel文…...
常用的跨域方案有哪些?
在前端开发中,跨域(Cross-Origin)是一个常见问题,通常是由于浏览器的同源策略(Same-Origin Policy)限制导致的。为了解决跨域问题,前端开发者可以采用多种方案。 1. CORS(跨域资源共…...
JS通过ASCII码值实现随机字符串的生成(可指定长度以及解决首位不出现数值)
在之前写过一篇“JS实现随机生成字符串(可指定长度)”,当时写的过于简单和传统,比较粗放。此次针对此问题,对随机生成字符串的功能进行优化处理,对随机取到的字符都通过程序自动来完成。 在写之前ÿ…...
IoTDB 1.2 升级 1.3 后 Pipe 插件失效
问题现象 客户使用 Pipe 功能将数据从 IoTDB 系统传输至 Kafka 集群,以便进行后续的数据处理与分析。在从企业版 1.2.5 升级至企业版 1.3.3.6 后,客户反馈 Kafka 的 consumer 无法接收到数据。经检查日志,发现存在以下报错: 问题…...
基于STM32的智能门锁安防系统(开源)
目录 项目演示 项目概述 硬件组成: 功能实现 1. 开锁模式 1.1 按键密码开锁 1.2 门禁卡开锁 1.3 指纹开锁 2. 功能备注 3. 硬件模块工作流程 3.1 步进电机控制 3.2 蜂鸣器提示 3.3 OLED显示 3.4 指纹与卡片管理 项目源代码分析 1. 主程序流程 (main…...
浅谈云端编辑器,分析其亮点与不足
浅谈云端编辑器,分析其亮点与不足 这个云端编辑器界面可以分为左侧题目筛选栏、中间题目描述与代码编辑区域、右侧AI提示功能三部分。以下是详细的分析: 1. 左侧题目筛选栏 层次结构清晰:左侧栏展示了一个层级结构,题目按主题分…...
Python字符串引号的嵌套问题
目录 1、使用不同类型的引号 2、使用转义字符 3、使用三重引号 4、嵌套三重引号 5、注意事项 在Python中,字符串可以使用单引号 () 或双引号 (") 来定义,但是如果我们要定义的字符串内也包含引号,字符串界定符的不正确使用会导致语法…...
latex如何让目录后面有点
使用前效果 在导言区引入以下代码 \usepackage[subfigure]{tocloft} \usepackage{subfigure} % 设置目录中 section 条目前导符号为连续点 \renewcommand{\cftsecleader}{\cftdotfill{\cftdotsep}}编译后的效果...
【力扣系列题目】不同路径 组合总和 最大连续1个数 打家劫舍{持续更新中...}
文章目录 不同路径不同路径[不同路径 II](https://leetcode.cn/problems/unique-paths-ii/)[不同路径 III](https://leetcode.cn/problems/unique-paths-iii/) 组合总和组合总和 【无重复数字无限制选择次数】[组合总和 II](https://leetcode.cn/problems/combination-sum-ii/)…...
方法建议ChatGPT提示词分享
方法建议 ChatGPT能够根据您的具体需求提供针对性的建议,帮助您选择最合适的研究方法。通过清晰的提示,ChatGPT可以精准地为您提供最契合的研究方案。此外,它还能协助您将这些方法灵活地应用于新的研究环境,提出创新的技术解决方案…...
Cursor的详细使用指南
以下是一份关于 Cursor 的详细使用指南: 一、安装与设置 下载与安装: 首先,访问 Cursor 的官方网站,根据你的操作系统(Windows、Mac 或 Linux)下载相应的安装程序。运行安装程序,按照屏幕上的提…...
Python----Python高级(正则表达式:语法规则,re库)
一、正则表达式 1.1、概念 正则表达式,又称规则表达式,(Regular Expression,在代码中常简写为regex、 regexp或RE),是一种文本模式,包括普通字符(例如,a 到 z 之间的字母࿰…...
电脑如何访问手机文件?
手机和电脑已经深深融入了我们的日常生活,无时无刻不在为我们提供服务。除了电脑远程操控电脑外,我们还可以在电脑上轻松地访问Android或iPhone手机上的文件。那么,如何使用电脑远程访问手机上的文件呢? 如何使用电脑访问手机文件…...
计算最接近的数
计算最接近的数 真题目录: 点击去查看 E B卷 100分题型 题目描述 给定一个数组X和正整数K,请找出使表达式: X[i] - X[i 1] - … - X[i K - 1] 结果最接近于数组中位数的下标 i ,如果有多个 i 满足条件,请返回最大的 i. 其中&…...
Ubuntu离线docker compose安装DataEase 2.10.4版本笔记
1、先准备一个可以正常上网的相同版本的Ubuntu系统,可以使用虚拟机。Ubuntu系统需要安装好docker compose或docker-compose 2、下载dataease-online-installer-v2.10.4-ce.tar在线安装包,解压并执行install.sh进行安装和启动 3、导出docker镜像 sudo d…...
C#使用WMI获取控制面板中安装的所有程序列表
C#使用WMI获取控制面板中安装的所有程序列表 WMI 全称Windows Management Instrumentation,Windows Management Instrumentation是Windows中用于提供共同的界面和对象模式以便访问有关操作系统、设备、应用程序和服务的管理信息。如果此服务被终止,多数基于 Windo…...
WPF2-1在xaml为对象的属性赋值.md
1. AttributeValue方式 1.1. 简单属性赋值1.2. 对象属性赋值 2. 属性标签的方式给属性赋值3. 标签扩展 (Markup Extensions) 3.1. StaticResource3.2. Binding 3.2.1. 普通 Binding3.2.2. ElementName Binding3.2.3. RelativeSource Binding3.2.4. StaticResource Binding (带参…...
社区版Dify实现文生视频 LLM+ComfyUI+混元视频
社区版Dify实现文生视频 LLMComfyUI混元视频 一、 社区版Dify实现私有化混元视频效果二、为什么社区版Dify可以在对话框实现文生视频?LLMComfyUI混元视频 实现流程图(重点)1. 文生视频模型支持ComfyUI2. ComfyUI可以轻松导出API实现封装3. Di…...
QT调用OpenSceneGraph
OSG和osgQt编译教程,实测通过 一、下载OpenSceneGraph OpenSceneGraphhttps://github.com/openscenegraph/OpenSceneGraph 二、使用CMAKE编译OpenSceneGraph 1.打开cmake,配置源代码目录 2. CMAKE_INSTALL_PREFIX设置为install文件夹,生…...
Qt基础项目篇——Qt版Word字处理软件
一、核心功能 本软件为多文档型程序,界面是标准的 Windows 主从窗口 拥有:主菜单、工具栏、文档显示区 和 状态栏。 所要实现的东西,均在下图了。 开发该软件,主要分为下面三个阶段 1)界面设计开发 多窗口 MDI 程序…...
【Postgres_Python】使用python脚本批量创建和导入多个PG数据库
之前批量创建和导入数据库分为2个python脚本进行,现整合优化代码合并为一个python脚本,可同步实现数据库的创建和数据导入。之前的文章链接: 【Postgres_Python】使用python脚本批量创建PG数据库 【Postgres_Python】使用python脚本将多个.S…...
消息队列篇--原理篇--RabbitMQ和Kafka对比分析
RabbitMQ和Kafka是两种非常流行的消息队列系统,但它们的设计哲学、架构特点和适用场景存在显著差异。对比如下。 1、架构设计 RabbitMQ: 基AMQP协议:RabbitMQ是基于AMQP(高级消息队列协议)构建的,支持多…...
俄语画外音的特点
随着全球媒体消费的增加,语音服务呈指数级增长。作为视听翻译和本地化的一个关键方面,画外音在确保来自不同语言和文化背景的观众能够以一种真实和可访问的方式参与内容方面发挥着重要作用。说到俄语,画外音有其独特的特点、挑战和复杂性&…...
【机器学习实战中阶】音乐流派分类-自动化分类不同音乐风格
音乐流派分类 – 自动化分类不同音乐风格 在本教程中,我们将开发一个深度学习项目,用于自动化地从音频文件中分类不同的音乐流派。我们将使用音频文件的频率域和时间域低级特征来分类这些音频文件。 对于这个项目,我们需要一个具有相似大小和相似频率范围的音频曲目数据集…...
Keil5 IDE使用笔记
1 Keil生成bin文件 $K\ARM\ARMCLANG\bin\fromelf.exe --bin --outputL/L.bin !L $K: 表示 Keil 5的安装路径 L: 表示 工程名 !L: 表示 工程名.arf 后缀的文件 可根据实际需要修改 --output 的值调整生成的bin文件的存放路径。 2 下载程序报错 No ST-LINK detected Error: Fla…...
自动化办公|使用Python重命名并移动文件到对应文件夹
在日常的文件管理和处理过程中,我们可能会遇到需要将文件整理到不同文件夹中的需求。例如,我们有一个包含多个文件的目录,文件名的首字符表示文件应该存放在哪个文件夹中。我们可以使用Python脚本来自动完成这个任务,实现文件的分…...
【全栈】SprintBoot+vue3迷你商城(5)
【全栈】SprintBootvue3迷你商城(5) 上一期我们基本完成了与用户相关的接口,而这些接口都是用户才能干的事情,如果你没登录,那么这些接口功能你都不能实现。 那么如何做到这一步呢? 1.Token 作用 身份…...