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').value
    const 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请求 默认请求方法为GET
      const 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) {
        // 接口文档规定接受的字符是JSON
        const jsonStr = JSON.stringify(config.data)
        // 请求头
        xhr.setRequestHeader('Content-Type','application/json')
        xhr.send(jsonStr)
      } else {
        xhr.send()
      }
     })
  }

04 案例 - 天气预报

BV1MN411y7——P43

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/457804.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

sqllab第二十一关通关笔记

知识点&#xff1a; 错误注入 最大长度为32超过需要利用截取函数分段读取cookie注入base64加密会保留符号的原始属性 通过admin admin进行登录发现和第二十关显示的内容一样&#xff0c;猜测应该还是cookie注入&#xff1b; 直接截取带有cookie的数据包&#xff0c;发现uname…

SpringBoot异常:类文件具有错误的版本 61.0, 应为 52.0的解决办法

问题&#xff1a; java: 无法访问org.mybatis.spring.annotation.MapperScan 错误的类文件: /D:/Program Files/apache-maven-3.6.0/repository/org/mybatis/mybatis-spring/3.0.3/mybatis-spring-3.0.3.jar!/org/mybatis/spring/annotation/MapperScan.class 类文件具有错误的…

YOLO_项目环境配置

YOLOv5官方项目地址 https://github.com/ultralytics/yolov5 下载 5.0和1.0源码 5.0 master-Tags-v5.0 Code-Download.ZIP 切换到1.0下载 解压缩提取 打开V5.0 使用Pycharm打开V5.0的文件夹 环境配置 参考 http://t.csdnimg.cn/Zdfh2 http://t.csdnimg.cn/Nqkwr 然后在Pyc…

AVCE - AV Evasion Craft Online 更新 8 种加载方式 - 过 WD 等

免责声明&#xff1a;本工具仅供安全研究和教学目的使用&#xff0c;用户须自行承担因使用该工具而引起的一切法律及相关责任。作者概不对任何法律责任承担责任&#xff0c;且保留随时中止、修改或终止本工具的权利。使用者应当遵循当地法律法规&#xff0c;并理解并同意本声明…

Redis:持久化、线程模型、大 key

Redis持久化方式有什么方式&#xff1f; Redis 的读写操作都是在内存中&#xff0c;所以 Redis 性能才会高&#xff0c;但是当 Redis 重启后&#xff0c;内存中的数据就会丢失&#xff0c;那为了保证内存中的数据不会丢失&#xff0c;Redis 实现了数据持久化的机制&#xff0c…

Linux的一些常用指令

一、文件中 r w x - 的含义 r&#xff08;read&#xff09;是只读权限&#xff0c; w&#xff08;write&#xff09;是写的权限&#xff0c; x&#xff08;execute&#xff09;是可执行权限&#xff0c; -是没有任何权限。 二、一些指令 # 解压压缩包 tar [-zxvf] 压缩包名…

【计算机网络】概述

文章目录 一、Internet 因特网1.1 网络、互联网、因特网1.2 因特网的组成 二、三种交换方式2.1 电路交换 &#xff08;Circuit Switching&#xff09;2.2 *分组交换 &#xff08;Packet Switching&#xff09;2.3 报文交换 &#xff08;Message Switching&#xff09; 三、计算…

2023版IDEA永久破解教程带patch.exe破解程序

2023版IDEA永久破解教程带patch.exe破解程序 第零步&#xff1a;百度云盘获取程序第一步&#xff1a;关闭电脑的病毒和危险防护&#xff08;目的是避免电脑自动清除破解程序&#xff09;1.找到电脑的 病毒和威胁防护2.蓝色按钮表示防护处于开启状态3.关闭成功会展示“实时保护已…

Ansible非标记语言YAML与任务剧本Playbook

前言 上篇介绍了 Ansible 单模块&#xff08;AD-Hoc&#xff09;的相关内容Ansible自动化运维Inventory与Ad-Hoc-CSDN博客&#xff0c;Ad-Hoc 命令是一次性的、即时执行的命令&#xff0c;用于在远程主机上执行特定任务&#xff0c;这些命令通常用于快速执行简单的任务。当需要…

软件无线电系列——模拟无线电、数字无线电、软件无线电

本节目录 一、模拟无线电 二、数字无线电 1、窄带数字无线电 2、宽带数字无线电 三、软件无线电本节内容 一、模拟无线电 20世纪80年代的模拟体制(美国的AMPS/欧洲的TACS)被称为第一代移动通信&#xff0c;简称1G,主要目标是为在大范围内有限的用户提供移动电话服务。最主要的…

React——react 的基本使用

前提&#xff1a;安装全局的脚手架&#xff0c;通过create-creat-app 项目名&#xff0c;我们创建好一个新项目&#xff0c;cd进去&#xff0c;通过npm start去运行该项目 注意&#xff1a;简单看下demo的配置&#xff0c;在根目录我们可以看到&#xff0c;没有任何webpack的…

【b站咸虾米】2 Vue基础(下) 2021最新Vue从基础到实例高级_vue2_vuecli脚手架博客案例

课程地址&#xff1a;【2021最新Vue从基础到实例高级_vue2_vuecli脚手架博客案例】 https://www.bilibili.com/video/BV1pz4y1S7bC/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 目录 2 Vue基础 下 2.8 计算属性 2.8.1 计算属性使用 2.8.2 计算…

整型变量的原子操作

什么是原子操作 原子操作&#xff08;Atomic Operation&#xff09;是指不可中断的操作&#xff0c;即在多线程环境下&#xff0c;当一个线程在执行原子操作时&#xff0c;不会被其他线程的调度和中断所影响。这种操作在多线程编程中尤为重要&#xff0c;因为它能保证操作的原…

Git如何清除账户凭证

场景&#xff1a;一般发生在Git用户变更的情况 1.git base 操作 Git会使用凭证助手 credential.helper来储存账户凭证&#xff0c;通过以下命令移除&#xff1a; git config --system --unset credential.helper 除了system系统级外&#xff0c;还有 global、local范围。 查…

直方图均衡化原理和实现

基本思想 将原始图像的直方图分布转换为一个均匀分布的直方图&#xff0c;这样原图中的高频率亮度值会被展宽&#xff0c;而低频率亮度值则被压缩&#xff0c;从而达到增强图像对比度的效果。 计算过程 假设我们有一个灰度图像&#xff0c;其像素值范围从0到L-1&#xff08;…

云计算 3月11号 (NFS远程共享存储及vsftpd配置)

构建NFS远程共享存储 一、NFS介绍 文件系统级别共享&#xff08;是NAS存储&#xff09; --------- 已经做好了格式化&#xff0c;可以直接用。 速度慢比如&#xff1a;nfs&#xff0c;sambaNFS NFS&#xff1a;Network File System 网络文件系统&#xff0c;NFS 和其他文件…

关于使用elementUI中select和el-checkbox-group的回显问题

网上看到很关于这个的问题回显&#xff0c;各式各样&#xff0c;没有绝句自己的问题&#xff0c;总重问题出在数据格式上 select和el-checkbox-group el-checkbox 都是字符串数组格式&#xff1a;[12,13,....]; 我写的格式是id是选中的id组成的回显数据格式&#xff1b; 如…

Flutter 多语言自动化本地化生成器

Flutter 多语言自动化本地化生成器 这是一个为Flutter设计的插件&#xff0c;通过从Excel表格提取的CSV文件自动生成Dart本地化文件&#xff0c;以简化应用程序本地化的流程。这个工具通过自动化创建多语言资源文件&#xff0c;简化了开发人员和翻译人员的工作流程。 特点 默…

Android 录屏操作

Android 录屏操作 本文主要介绍android中如何通过MediaRecorder实现录屏操作的. 1: 申请权限 <uses-permission android:name"android.permission.RECORD_AUDIO" /> <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE"…

react native常用插件

react-native-async-storage/async-storage 说明&#xff1a;AsyncStorage 是一个在 react-native 中轻量存储的库&#xff1b;跟 localStorage 类似&#xff0c;API 也几乎一样&#xff1b;存储的时候需要将存储内容转成字符串存储。 react-navigation/material-bottom-tabs …