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

AJAX 03 XMLHttpRequest、Promise、封装简易版 axios

AJAX 学习

  • AJAX 3 原理
    • 01 XMLHttpRequest
      • ① XHR 定义
      • ② XHR & axios 关系
      • ③ 使用 XHR
      • ④ XHR查询参数
      • 案例:地区查询(URLSearchParams)
      • ⑤ XHR数据提交 POST
    • 02 Promise
      • Promise 使用
      • Promise - 三种状态
      • 案例:使用Promise + XHR 获取省份列表
    • 03 封装简易版 axios
      • 完善1 myAxios-支持传递查询参数
      • 完善2 myAxios-支持传递请求体数据
    • 04 案例 - 天气预报

AJAX 3 原理

01 XMLHttpRequest

① XHR 定义

在这里插入图片描述

② XHR & axios 关系

axios 内部采用 XMLHttpRequest 与服务器交互

在这里插入图片描述

学习XHR的好处:掌握使用 XHR 与服务器进行数据交互,了解 axios 内部原理

③ 使用 XHR

步骤:

  1. 创建 XMLHttpRequest 对象
  2. 配置请求方法和请求 url 地址
  3. 监听 loadend 事件,接收响应结果
  4. 发起请求

在这里插入图片描述

举例:

在axios中,会自动把提交/返回的 JSON 字符串转变为数组,但是原生的 XMLHttpRequest 不会。

  // 1. 创建 XMLHttpRequest 对象const xhr = new XMLHttpRequest()// 2. 配置请求方法和请求 url 地址xhr.open('GET','http://hmajax.itheima.net/api/province')// 3. 监听 loadend 事件,接收响应结果// loadend :请求和相应都完成了,就会触发这个回调函数xhr.addEventListener('loadend', () => {console.log(xhr.response);const data = JSON.parse(xhr.response)console.log(data);})// 4. 发起请求xhr.send()
1. AJAX 原理是什么?
➢ XMLHttpRequest 对象
2. 为什么学习 XHR?
➢ 有更多与服务器数据通信方式
➢ 了解 axios 内部原理
3. XHR 使用步骤?
➢ 创建 XHR 对象
➢ 调用 open 方法,设置 url 和请求方法
➢ 监听 loadend 事件,接收结果
➢ 调用 send 方法,发起请求

④ XHR查询参数

定义:浏览器提供给服务器的额外信息,让服务器返回浏览器想要的数据

语法:http://xxxx.com/xxx/xxx?参数名1=值1&参数名2=值2

在这里插入图片描述

区别axios,axios中有一个params的参数,会自动把里面的参数 拼接到url中,但是XHR中没有,我们可以利用 URLSearchParams

举例:

  const xhr = new XMLHttpRequest()xhr.open('GET','http://hmajax.itheima.net/api/city?pname=辽宁省')xhr.addEventListener('loadend', () => {console.log(xhr.response);const text = document.querySelector('.text')text.innerHTML = JSON.parse(xhr.response).list.join('<br>')})xhr.send()

案例:地区查询(URLSearchParams)

需求:输入省份和城市名字,查询地区列表

请求地址:http://hmajax.itheima.net/api/area?参数名1=值1&参数名2=值2

  • 注意上面的参数名 是后端规定的

在表单中输入省份、城市的名字,获取对象。我们要传递两个参数到服务器,传递多个参数的语法如上。不过这里是需要在表单中获取。可以自己定义一个对象,然后转换成参数名1=值1&参数名2=值2这样的格式,不过可以借助插件。
在这里插入图片描述

  /*** 目标: 根据省份和城市名字, 查询对应的地区列表*/// 1. 查询按钮-点击事件document.querySelector('.sel-btn').addEventListener('click', () => {// 2. 收集省份和城市名字const pname = document.querySelector('.province').valueconst cname = document.querySelector('.city').value// 3. 组织查询参数字符串const qObj = {pname,cname}// 查询参数对象 -> 查询参数字符串const paramsObj = new URLSearchParams(qObj)const queryString = paramsObj.toString()console.log(queryString)// 4. 使用XHR对象,查询地区列表const xhr = new XMLHttpRequest()xhr.open('GET', `http://hmajax.itheima.net/api/area?${queryString}`)xhr.addEventListener('loadend', () => {console.log(xhr.response)const data = JSON.parse(xhr.response)console.log(data)const htmlStr = data.list.map(areaName => {return `<li class="list-group-item">${areaName}</li>`}).join('')console.log(htmlStr)document.querySelector('.list-group').innerHTML = htmlStr})xhr.send()})

⑤ XHR数据提交 POST

以注册账号为例。

需求:通过 XHR 提交用户名和密码,完成注册功能

核心:

请求头设置 Content-Type:application/json

请求体携带 JSON 字符串

注意:请求体Body参数对应axios中的data属性

在这里插入图片描述

案例:

<body><button class="reg-btn">注册</button>
</body>
<script>/*** 目标:使用XHR进行数据提交-完成注册功能*/// 点击注册按钮之后触发注册时间document.querySelector('.reg-btn').addEventListener('click',() => {// 假数据const newObj = {username: '11111111',password: '11111111'}// 1. 创建 XMLHttpRequest 对象const xhr = new XMLHttpRequest()// 2. 配置请求方法和请求 url 地址xhr.open('POST', 'http://hmajax.itheima.net/api/register')// 3. 监听 loadend 事件,接收响应结果// loadend :请求和相应都完成了,就会触发这个回调函数xhr.addEventListener('loadend', () => {console.log(xhr.response);})// 设置请求头 xhr.setRequestHeader('Content-Type','application/json')const usrStr = JSON.stringify(newObj)// 4. 发起请求xhr.send(usrStr)})
</script>

02 Promise

Promise 使用

Promise对象用于表示一个异步操作的最终完成(或失败)及其结果值。

学过的异步代码: setTimeout、 setInterval、AJAX

使用Promise管理异步任务

好处:

  1. 逻辑更清晰
  2. 了解 axios 函数内部运作机制
  3. 能解决回调函数地狱问题

语法:
在这里插入图片描述

注意 : catch中打印error,不能用 console.log(error) ,而是要用 console.dir(error)

案例:

  // 目标:使用Promise管理异步任务// 1 创建Promis对象const p = new Promise((resolve,reject) => {// 2 执行异步代码setTimeout(()=> {// resolve('模拟AJAX请求-成功结果')reject(new Error('模拟AJAX请求-失败结果'))}, 2000)})// 3 获取结果p.then(result => {console.log(result);}).catch(error => {console.log(error);})
1. 什么是 Promise?
➢ 表示(管理)一个异步操作最终状态和结果值的对象
2. 为什么学习 Promise?
➢ 成功和失败状态,可以关联对应处理程序
➢ 了解 axios 内部原理(知道了axios的then和catch是怎么来的了)
3. Promise 使用步骤?

Promise - 三种状态

作用:了解Promise对象如何关联地处理函数,以及代码执行顺序

概念:一个Promise对象,必然处于以下几种状态之一

✓ 待定(pending) :初始状态,既没有被兑现,也没有被拒绝

✓ 已兑现(fulfilled) :意味着,操作成功完成

✓ 已拒绝(rejected) :意味着,操作失败

注意:Promise对象一旦被兑现/拒绝就是已敲定了,状态无法再被改变

在这里插入图片描述

  // 创建Promis对象 pending 待定状态const p = new Promise((resolve,reject) => {// Promis对象 创建时,这里的代码都会执行了setTimeout(()=> {// resolve() => 'fullfilled状态-已兑现' => then()// resolve('模拟AJAX请求-成功结果')// reject() => 'rejected状态-已拒绝' => catch()reject(new Error('模拟AJAX请求-失败结果'))}, 2000)})console.log(p); // pending 待定状态// 3 获取结果p.then(result => {console.log(result);}).catch(error => {console.log(error);})
总结:
1. Promise 对象有哪 3 种状态?
➢ 待定 pending
➢ 已兑现 fulfilled
➢ 已拒绝 rejected
2. Promise 状态有什么用?
➢ 状态改变后,调用关联的处理函数

案例:使用Promise + XHR 获取省份列表

需求:使用 Promise 管理 XHR 获取省份列表,并展示到页面上

步骤:

  1. 创建 Promise 对象
  2. 执行 XHR 异步代码,获取省份列表
  3. 关联成功或失败函数,做后续处理
<body><p class="my-p"></p>
</body><script>const p = new Promise((resolve,reject) => {const xhr = new XMLHttpRequest()xhr.open('GET','http://hmajax.itheima.net/api/province11')xhr.addEventListener('loadend', () => {console.log(xhr);// console.log(xhr.response);// 怎么把 XHR 和 Promise 联系起来// 利用响应状态码if(xhr.status >= 200 && xhr.status < 300) {resolve(xhr.response)} else {reject(new Error(xhr.response))}})xhr.send()})p.then(result => {console.log(result);const myP = document.querySelector('.my-p')myP.innerHTML = JSON.parse(result).list.join('<br>')}).catch(error => {console.dir(error)const myP = document.querySelector('.my-p')myP.innerHTML = error.message})
</script>

03 封装简易版 axios

需求:基于 Promise + XHR 封装 myAxios 函数,获取省份列表展示

步骤:

  1. 定义 myAxios 函数,接收配置对象,返回 Promise 对象

    为什么要有配置对象:调用axios的时候,传进了url、params、data配置对象。为什么要返回Promise对象,因为我们在使用axios后,还可以使用 then catch。

  2. 发起 XHR 请求,默认请求方法为 GET

  3. 调用成功/失败的处理程序

  4. 使用 myAxios 函数,获取省份列表展示

在这里插入图片描述

<body><p class="myp"></p>
</body>
<script>// 需求:基于 Promise + XHR 封装 myAxios 函数,获取省份列表展示function myAxios(config) { // config是一个对象!return new Promise((resolve, reject) => {// 发起XHR请求 默认请求方法为GETconst xhr = new XMLHttpRequest()xhr.open(config.method || 'GET', config.url)xhr.addEventListener('loadend', ()=>{if(xhr.status >= 200 && xhr.status < 300) {// 这里要模仿axios,axios是自动转换JSON字符的resolve(JSON.parse(xhr.response))} else {reject(new Error(xhr.response))}})xhr.send()})}myAxios({url: 'http://hmajax.itheima.net/api/province'}).then(result => {console.log(result);const myp = document.querySelector('.myp')myp.innerHTML = result.list.join('<br>')}).catch(error => {console.log(error);const myp = document.querySelector('.myp')myp.innerHTML = error.message})
</script>

完善1 myAxios-支持传递查询参数

需求:修改 myAxios 函数支持传递查询参数,获取"辽宁省","大连市"对应地区列表展示

步骤:

  1. myAxios 函数调用后,判断 params 选项
  2. 基于 URLSearchParams 转换查询参数字符串
  3. 使用自己封装的 myAxios 函数展示地区列表
  // 需求:修改 myAxios 函数支持传递查询参数,获取"辽宁省","大连市"对应地区列表展示function myAxios(config) { return new Promise((resolve, reject) => {const xhr = new XMLHttpRequest()// 1 判断有params选项,携带查询参数if(config.params) {// 2 使用 URLSearchParams 转换,并携带url上const paramsObj = new URLSearchParams(config.params)const queryString = paramsObj.toString()// 把查询参数字符串,拼接在url ? 后面config.url += `?${queryString}`}xhr.open(config.method || 'GET', config.url)xhr.addEventListener('loadend', ()=>{if(xhr.status >= 200 && xhr.status < 300) {resolve(JSON.parse(xhr.response))} else {reject(new Error(xhr.response))}})xhr.send()})}

完善2 myAxios-支持传递请求体数据

需求:修改 myAxios 函数支持传递请求体数据,完成注册用户功能

步骤:

  1. myAxios 函数调用后,判断 data 选项
  2. 转换数据类型,在 send 方法中发送
  3. 使用自己封装的 myAxios 函数完成注册用户功能
    在这里插入图片描述
function myAxios(config) { return new Promise((resolve, reject) => {const xhr = new XMLHttpRequest()if(config.params) {const paramsObj = new URLSearchParams(config.params)const queryString = paramsObj.toString()config.url += `?${queryString}`}xhr.open(config.method || 'GET', config.url)xhr.addEventListener('loadend', ()=>{if(xhr.status >= 200 && xhr.status < 300) {resolve(JSON.parse(xhr.response))} else {reject(new Error(xhr.response))}})// 1 判断有data选项,携带请求体if(config.data) {// 接口文档规定接受的字符是JSONconst jsonStr = JSON.stringify(config.data)// 请求头xhr.setRequestHeader('Content-Type','application/json')xhr.send(jsonStr)} else {xhr.send()}})}

04 案例 - 天气预报

BV1MN411y7——P43

相关文章:

AJAX 03 XMLHttpRequest、Promise、封装简易版 axios

AJAX 学习 AJAX 3 原理01 XMLHttpRequest① XHR 定义② XHR & axios 关系③ 使用 XHR④ XHR查询参数案例&#xff1a;地区查询&#xff08;URLSearchParams&#xff09;⑤ XHR数据提交 POST 02 PromisePromise 使用Promise - 三种状态案例&#xff1a;使用Promise XHR 获取…...

如何将办公资料文件生成二维码?扫码可看详情

日常办公的时候&#xff0c;经常会需要应用二维码来向同事或者客户发送和展示一些资料。比如包含企业介绍和产品介绍的资料、一些操作流程的资料、产品展示宣传视频、活动安排详情、比赛流程、会议资料… 这些都能通过一个文件二维码来展示。 文件二维码支持将PDF文件生成二维…...

【Streamlit学习笔记】实现包含多个sheet的excel文件下载

1、什么是Streamlit Streamlit是一个免费的开源框架&#xff0c;用于快速构建和共享漂亮的机器学习和数据科学Web应用程序&#xff0c;官网链接 Streamlit Streamlit API链接 API reference 实际项目中遇到的问题&#xff1a;包含多个sheet的excel文件下载&#xff0c;下面将给…...

[Redis]——主从同步原理(全量同步、增量同步)

目录 Redis集群&#xff1a; 主从同步原理&#xff1a; replid和offset: 全量同步和增量同步&#xff1a; repl_baklog文件&#xff1a; 主从集群的优化&#xff1a; Redis集群&#xff1a; 部署多台Redis我们称之为Redis集群&#xff0c;他有一个主节点(负责写操作)&…...

Buildroot 之二 详解构建架构、流程、external tree、示例

构建系统 Buildroot 中的构建系统使用的是从 Linux Kernel(4.17-rc2) 中移植的 Kconfig(配置) + Makefile & Kbuild(编译)这套构建系统,移植后的源码位于 support/kconfig/ 目录下。Buildroot 本身是一个构建系统,与直接编译源码不同,因此,它对这套系统进行了比较…...

牛客小白月赛61-C-小喵觅食

很经典的bfs,就是从猫咪和MM的坐标开始bfs搜索 不过这题有些小细节需要注意 1.认真审题,注意,猫一旦闻到小鱼干的味道,开始动,此时MM就不动了,一开始没仔细审题,很不好的习惯 2.注意移动的条件,vis,不是墙,距离是MM的移动距离范围内 3.这个猫咪的r2是闻味道的r2,不是移动距…...

200 名专家编写报告:AI 发展可能对人类构成「灭绝级威胁」

3 月 14 日消息&#xff0c;美国国务院委托编写了一份新报告&#xff0c;警告 AI 正呈指数级发展&#xff0c;可能会对人类构成「灭绝级威胁」。 这份报告全称为《提高先进人工智能安全保障的行动计划》&#xff0c;要求美国政府必须迅速、果断地采取行动&#xff0c;以避免 A…...

学习Android的第二十九天

目录 Android Service 与 Activity 通讯 范例 Android Service Alarm 定时广播 Alarm Alarm 使用流程 范例 Android IBinder Binder 为什么是 Binder ? Android Service 与 Activity 通讯 Activity 与 Service 通信的媒介就是 Service 中的 onBind() 方法&#xff0…...

SpringMVC重点记录

目录 1.学习重点2.回顾MVC3.回顾servlet4.初始SpringMVC4.1.为什么要学SpringMVC?4.2.SpringMVC的中重点DispatcherServlet4.3.SpringMVC项目的搭建4.4.MVC框架要做哪些事情?4.5.可能会遇到的问题 5.SpringMVC的执行原理6.使用注解开发SpringMVC7.Controller控制总结8.RestF…...

一条 SQL 更新语句如何执行的

Server 层 存储引擎层 总流程 查询语句 连接器 查询缓存 分析器 优化器 执行器 更新语句 redo log&#xff08;节省的是随机写磁盘的 IO 消耗&#xff08;转成顺序写&#x…...

Github上哪些好用的安全工具1

专注于web漏洞挖掘、内网渗透、免杀和代码审计&#xff0c;感谢各位师傅的关注&#xff01;网安之路漫长&#xff0c;与君共勉&#xff01; URLFinder 一款快速提取网页信息的工具。该项目可以快速爬取网页上的 URL 地址、JS 文件里的 API 接口等信息&#xff0c;支持批量抓取…...

手写Mybatis自动填充插件

目录 一、Mybatis插件简介&#x1f959;二、工程创建及前期准备工作&#x1f96b;实现代码配置文件 三、插件核心代码实现&#x1f357;四、测试&#x1f953; 一、Mybatis插件简介&#x1f959; Mybatis插件运行原理及自定义插件_简述mybatis的插件运行原理,以及如何编写一个…...

upload文件上传漏洞复现

什么是文件上传漏洞&#xff1a; 文件上传漏洞是指由于程序员在对用户文件上传部分的控制不足或者处理缺陷&#xff0c;而导致的用户可以越过其本身权限向服务器上上传可执行的动态脚本文件。这里上传的文件可以是木马&#xff0c;病毒&#xff0c;恶意脚本或者WebShell等。“…...

Docker 安装部署 SqlServer 数据库

Docker 安装部署 SqlServer 数据库 背景&#xff1a; ​ 最近在开发数据中台数据集成模块&#xff0c;需要对接大量的数据做测试&#xff0c; 由于SqlServer 下载安装会耗费大量时间&#xff0c;所以采用 Docker 安装 Sqlserver 的方式部署数据库。 1、拉去 sqlserver 镜像 …...

cmath 中cos sin等常用函数的坑(弧度角度换算)

cmath中三角函数的输入是弧度,不是角度.忘了这件事,找bug找了好久! 弧度是旧称弪。在数学和物理中&#xff0c;弧度是角的度量单位。它是由国际单位制导出的单位&#xff0c;单位缩写是rad。弧度是指在一个圆中&#xff0c;弧长和半径之比&#xff0c;即|弧度|弧长半径。 角度…...

深度解析HTTP反向代理-okey proxy

反向代理這個概念可能並不常見&#xff0c;但其實它對於提升網路安全和訪問速度方面發揮著很大作用。 HTTP反向代理&#xff08;HTTP Reverse Proxy&#xff09;是一種特殊的代理伺服器&#xff0c;首先它能夠接收互聯網上的連接請求&#xff0c;然後將這些請求轉發給內部網路…...

SwinIR训练报错解决

swinir训练报错解决 记录swinir图像超分重建算法复现过程中的报错信息,并提供相应的解决方案 报错信息 UserWarning: torch.meshgrid: in an upcoming release, it will be required to pass the indexing argument. (Triggered internally at C:\actions-runner\_work\pyto…...

C++类和对象一

#include <iostream> using namespace std;//设计一个学生类 class CStudent {public: //公有成员void InputData(){cout << "请输入学号";cin >> sno;cout << "请输入姓名";cin >> sname;cout << "请输入分…...

Linux之线程互斥

目录 一、问题引入 二、线程互斥 1、相关概念 2、加锁保护 1、静态分配 2、动态分配 3、锁的原理 4、死锁 三、可重入与线程安全 1、概念 2、常见的线程不安全的情况 3、常见的线程安全的情况 4、常见不可重入的情况 5、常见可重入的情况 6、可重入与线程安全联系…...

C++ 拷贝构造函数和运算符重载

目录 一. 拷贝构造函数 1. 引入 2. 拷贝构造的概念 3. 浅拷贝 4. 深拷贝 二. C运算符重载 1. 概念 2. 注意事项 3.举例 一. 拷贝构造函数 1. 引入 我们在创建对象时&#xff0c;能不能创建一个与原先对象一模一样的新对象呢&#xff1f;为了解决这个问题&#x…...

Java微服务在Istio中出现“偶发503 no healthy upstream”?7分钟定位Sidecar健康检查盲区与Liveness Probe冲突真相

第一章&#xff1a;Java微服务在Istio中偶发503问题的现象与影响在基于Istio构建的服务网格环境中&#xff0c;Java微服务&#xff08;尤其是采用Spring Cloud Kubernetes或原生Spring Boot Istio Sidecar部署模式&#xff09;频繁出现偶发性HTTP 503 Service Unavailable响应…...

手把手教你将自定义视频问答JSON转成EasyR1可用的Parquet数据集

手把手教你将自定义视频问答JSON转成EasyR1可用的Parquet数据集 当你在构建视频问答模型时&#xff0c;可能已经收集了大量结构化的JSON格式数据&#xff0c;但如何将这些数据适配到EasyR1框架中却成了一个技术难题。本文将为你提供一个从零开始的完整解决方案&#xff0c;解决…...

8种Prompt优化技巧:解决大模型输出不稳定痛点

8种Prompt优化技巧&#xff1a;解决大模型输出不稳定痛点 在大模型应用落地过程中&#xff0c;开发者常遇到输出结果不可控的问题&#xff1a;同样的需求多次调用返回内容差异巨大、回答偏离核心要求、格式混乱无法直接解析&#xff0c;这些问题严重影响业务流程的稳定性和用户…...

trae中安装mcp报Cannot find package/ERR_MODULE_NOT_FOUND问题

简介 我在trae中安装高德地图的mcp和其他的mcp报出了以下错误&#xff0c;以此记录并分享给大家。 新的改变 node:internal/modules/esm/resolve:204 const resolvedOption FSLegacyMainResolve(pkgPath, packageConfig.main, baseStringified); ^ Error: Cannot find pack…...

实战指南:基于快马平台与Touchgal,从零开发移动端手写绘图应用

今天想和大家分享一个实战项目&#xff1a;基于Touchgal开发移动端手写绘图应用。这个项目特别适合需要复杂手势交互的场景&#xff0c;比如绘图软件、地图导航等。下面我会详细介绍整个开发流程和关键实现点。 项目初始化与环境搭建 首先需要创建一个基础的HTML5项目结构。画…...

HiOmics平台:零代码实现ChIP-Seq数据可视化与深度解析

1. 为什么科研人员需要零代码ChIP-Seq分析工具 做表观遗传学研究的朋友们应该都深有体会&#xff0c;ChIP-Seq数据分析就像一场马拉松——从原始数据清洗、序列比对、peak calling到功能注释&#xff0c;每个环节都需要不同的工具和脚本。我刚开始接触这个领域时&#xff0c;光…...

新手最值得入的一款ai音乐工具

2026年&#xff0c;ai音乐爆发的一年。国内国外各种AI音乐工具层出不穷。想要尝试AI音乐的新手宝宝该怎么去选择呢&#xff1f;市面上大大小小的ai音乐创作软件我基本都尝试过。我觉得只有一款工具是最值得推荐的&#xff0c;也是我使用的最多的。那就是蘑兔AI&#xff0c;你们…...

用STM32和示波器搞定美的/格力空调红外遥控(附完整C代码)

STM32实战&#xff1a;从示波器捕获到空调红外协议逆向全解析 红外遥控技术看似简单&#xff0c;却蕴含着精妙的时序设计和协议逻辑。作为一名长期混迹于硬件开发领域的工程师&#xff0c;我经常遇到需要逆向控制家电的场景。最近在智能家居项目中&#xff0c;就遇到了需要通过…...

番茄小说下载器:Rust构建的高性能离线阅读解决方案

番茄小说下载器&#xff1a;Rust构建的高性能离线阅读解决方案 【免费下载链接】Tomato-Novel-Downloader 番茄小说下载器不精简版 项目地址: https://gitcode.com/gh_mirrors/to/Tomato-Novel-Downloader 在数字阅读时代&#xff0c;网络依赖、格式不兼容和下载效率低下…...

工艺智能如何让汽车涂装质量更稳、成本更低?

一辆汽车的车身涂层究竟需要经历怎样的极限挑战&#xff1f;从出厂时如镜面般的光泽&#xff0c;到在十年风雨中抵御紫外线、酸雨和砂石的侵蚀&#xff0c;涂装工艺正是赋予汽车这幅铠甲的关键。然而&#xff0c;在过去&#xff0c;这道工序高度依赖老师傅的经验&#xff0c;面…...