Ajax学习笔记

文章目录标题


Ajax学习笔记

定义:Ajax是异步的JavaScript和XML。简单来说就是使用XMLHttpRequest对象与服务器通信。它可以使用JSON、XML、HTML和text文本邓格式发送和接收数据。Ajax最吸引人的就是它的"异步"特性,也就是说它可以在不重新刷新页面的情况下与服务器通信、交换数据或更新页面。

概念:Ajax是浏览器与服务器进行数据通信的技术。

作用:浏览器和服务器之间通信,动态数据交互。

axios使用

axios体验步骤:

  • 引用axios库
  • 使用axios语法
html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <p class="my-p"></p>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script>
    axios({
      url: 'https://hmajax.itheima.net/api/province'
    }).then(result => {
      //console.log(result.data.list.join(`<br>`));
      document.querySelector('.my-p').innerHTML = result.data.list.join(`<br>`)
    })
  </script>
</body>

</html>

axios请求拦截器

axios请求拦截器:发起请求之前,出发点配置函数,对请求参数进行额外配置。

语法:

js 复制代码
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做什么
    return config
}, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error)
})

axios响应拦截器

axios响应拦截器:响应回到then/catch之前,触发的拦截函数,对响应的结果统一处理。

语法:

js 复制代码
axios.interceptors.response.use(function (response) {
  // 2xx范围内的状态码都会触发该函数
  // 对响应数据做些什么
  return response
}, function (error) {
  // 超出2xx范围的状态码都会触发该函数
  // 对响应错误做点什么。
  return Promise.reject(error)
})

优化axios响应结果

目标:axios直接接收服务器返回的响应结果。

form-serialize插件

作用:快速收集表单元素的值。

语法:serialize(form, { hash: true, empty: true })

  • form:获取的表单
  • hash:设置获取数据结构
    • true:JS对象
    • false:查询字符串
  • empty:设置是否获取空值
    • true:获取空值,使数据结构和标签结构一致
    • false:不获取空值
html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <form action="javascript:;">
    <input type="text" name="username">
    <br>
    <input type="text" name="password">
    <br>
    <input type="button" class="btn" value="提交">
  </form>
  <script src="../form-serialize.js"></script>
  <script>
    document.querySelector('.btn').addEventListener('click', () => {
      const form = document.querySelector('form')
      const data = serialize(form, { hash: true, empty: true })
      console.log(data);
    })
  </script>
</body>

</html>

图片上传

使用步骤:

  1. 获取图片文件对象

  2. 使用FormData携带图片文件

    js 复制代码
    const fd = new FormmData()
    fd.append(参数名, 值)
  3. 提交表单数据到服务器,使用图片url网址

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <input type="file" class="upload">
  <img src="" alt="">
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script>
    document.querySelector('.upload').addEventListener('change', e => {
      console.log(e.target.files[0]);
      const fd = new FormData()
      fd.append('img', e.target.files[0])
      axios({
        url: 'http://hmajax.itheima.net/api/uploadimg',
        method: 'post',
        data: fd
      }).then(result => {
        const imgurl = result.data.data.url
        document.querySelector('img').src = imgurl
      })
    })
  </script>
</body>

</html>

HTTP协议

HTTM协议:规定了浏览器发送及服务器返回内容的格式。

请求报文

请求报文:浏览器按照HTTP协议要求的格式,发送给服务器的内容。

组成部分:

  1. 请求行:请求方法,URL,协议
  2. 请求头:以键值对的格式携带的附加信息,比如Content-Type
  3. 空行:分隔请求头,空行之后的是发送给服务器的资源
  4. 请求体:发送的资源

相应报文

响应报文:服务器按照HTTP协议要求的格式,返回给浏览器的内容。

组成部分:

  1. 响应行(状态行):协议、HTTP响应状态码、状态信息

    • HTTP响应状态码:用来表明请求释放成功完成

    状态码 说明
    1xx 信息
    2xx 成功
    3xx 重定向信息
    4xx 客户端错误
    5xx 服务端错误
    • 比如:404(服务器找不到资源)
  2. 响应头:以键值对的格式携带的附加信息,比如Content-Type

  3. 空行:分隔响应头,空行之后是服务器返回的资源

  4. 响应体:返回的资源

接口文档

接口文档:描述接口的文章。

接口:使用AJAX和服务器通讯时,使用的URL、请求方法以及参数。

AJAX原理 - XMLHttpRequest

定义:XMLHttpRequest(XHG)对象用于与服务器交互。通过XMLHttpRequest可以在不刷新页面的情况下请求特定URL,获取数据。这允许网页在不影响用户操作的情况下,更新网页的局部内容。

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

使用XMLHttpRequest

使用步骤:

  1. 创建XMLHttpRequest对象

  2. 配置请求方法和请求url地址

  3. 监听loadend事件,接收响应结果

  4. 发起请求

    js 复制代码
        const xhr = new XMLHttpRequest()
        xhr.open('请求方法', '请求url网址')
        xhr.addEventListener('loadend', () => {
          console.log(xhr.response)
        })

XMLHttpRequest - 查询参数

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

例子:查询河北省的城市名称。

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <div></div>
  <script>
    const xhr = new XMLHttpRequest()
    xhr.open('get', 'https://hmajax.itheima.net/api/city?pname=河北省')
    xhr.addEventListener('loadend', () => {
      console.log(xhr.response);
      // 将字符串转成对象
      const data = JSON.parse(xhr.response) // 字符串转对象
      document.querySelector('div').innerHTML = data.list.join('<br>')
    })
    xhr.send()
  </script>
</body>

</html>
查询字符串对象

使用步骤:

  1. 创建URLSearchParams对象
  2. 生成固定格式查询参数的字符串
js 复制代码
    const paramsobj = new URLSearchParams({
      参数名1: 值1,
      参数名2: 值2
    })
    const queryString = paramsobj.toString() // 结果:参数名1=值1&参数名2=值2

XMLHttpRequest - 数据提交

核心:

  • 请求头设置Content-Type:application/json
  • 请求体携带JSON字符串
js 复制代码
    const xhr = new XMLHttpRequest()
    xhr.open('请求方法', '请求url网址')
    xhr.addEventListener('loadend', () => {
      console.log(xhr.response);
    })
    // 告诉服务器,传递的内容类型,是JSON字符串
    xhr.setRequestHeader('Content-Type', 'application/json')
    // 准备数据并转成JSON字符串
    const user = { username: 'itheima007', password: '7654321' }
    const userStr = JSON.stringify(user)
    xhr.send(userStr) // 发送请求体数据

事件循环

概念:JavaScript有一个基于事件循环的并发模型,事件循环负责执行代码、收集和处理事件以及执行队列中的子任务。

原因:JavaScript单线程(某一时刻只能执行一行代码),为了让耗时代码不阻塞其他代码运行,设计了事件循环。

执行过程

定义:执行代码和收集异步任务的模型,在调用栈空闲,反复调用任务队列里回调函数的执行机制,就叫事件循环。

js 复制代码
    console.log(1);
    setTimeout(() => {
      console.log(2);
    }, 2000)
    console.log(3);
    setTimeout(() => {
      console.log(4);
    }, 0)
    console.log(5);
    // 打印顺序:1 3 5 4 2

宏任务和微任务

ES6之后引入了Promise对象,让JS引擎也可以发起异步任务。

异步任务分为:

  • 宏任务:由浏览器环境执行的异步代码
  • 微任务:由JS引擎环境执行的异步代码
任务(代码) 执行所在环境
JS脚本执行事件(script) 浏览器
setTimeout/setInterval 浏览器
AJAX请求完成事件 浏览器
用户交互完成事件 浏览器
Promise对象.then() JS引擎

Promise本身是同步的,而then和catch回调函数是异步的。

因为微任务队列离JS引擎更近,所以先执行微任务队列里的代码,再执行宏任务队列里的代码。

js 复制代码
    console.log(1);
    setTimeout(() => {
      console.log(2);
    })
    const p = new Promise((resolve, reject) => {
      console.log(3);
      resolve(4)
    })
    p.then(result => {
      console.log(result);
    })
    console.log(5);
    // 打印顺序:1 3 5 4 2
js 复制代码
    console.log(1)
    setTimeout(() => {
      console.log(2)
      const p = new Promise(resolve => resolve(3))
      p.then(result => console.log(result))
    }, 0)
    const p = new Promise(resolve => {
      setTimeout(() => {
        console.log(4)
      }, 0)
      resolve(5)
    })
    p.then(result => console.log(result))
    const p2 = new Promise(resolve => resolve(6))
    p2.then(result => console.log(result))
    console.log(7)
    // 1 7 5 6 2 3 4

Promise对象

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

好处:

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

核心代码:

js 复制代码
    // 1.创建promise对象
    const p = new Promise((resolve, reject) => {
      // 2.执行异步任务并传递结果
      // 成功调用:resolve(值) 触发then()执行
      // 失败调用:reject(值) 触发catch()执行
    })
    // 3.接收结果
    p.then(result => {
      // 成功
    }).catch(error => {
      // 失败
    })

同步代码和异步代码

同步代码:逐步执行,需要原地等待结果后,才继续往下执行。

异步代码:调用后耗时,不阻塞代码继续执行(不必原地等待),在将来完成后触发一个回调函数。

JS中的异步代码:

  • setTimeout / setInterval
  • 事件
  • AJAX

异步代码通过回调函数接受结果。

回调函数地狱

概念:在回调函数中嵌套回调函数,一直嵌套下去就形成了回调函数地狱。

缺点:可读性差,异常无法捕获,耦合性严重,牵一发动全身。

Promise的三种状态

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

概念:一个Promise对象,必定处于以下三种状态之中:

  • 待定(pending):初始状态,既没有被兑现,也没有被拒绝
  • 已兑现(fulfilled):操作成功完成
  • 已拒绝(rejected):操作失败

注意:

  • promise对象一旦被兑现/拒绝,就是已敲定了,状态无法再被改变。
  • new promise()里的回调函数会立即执行

通过Promise+XHR模拟axios实现

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

步骤:

  1. 定义myAxios函数,接收配置对象,返回Promise对象
  2. 发起XHR请求,默认请求方法为get
  3. 调用成功/失败的处理程序
  4. 使用myAxios函数,获取省份列表展示

核心代码模板:

js 复制代码
    function myAxios (config){
      return new Promise((resolve, reject) => {
        // XHR请求
        // 调用成功/失败的处理程序
      })
    }
    myAxios({
      url: '目标资源地址'
    }).then(result => {

    }).catch(error => {
      
    })

完整实现代码:

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <p></p>
  <script>
    function myAxios(config) {
      return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest()
        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()
      })
    }

    myAxios({
      url: 'https://hmajax.itheima.net/api/province'
    }).then(result => {
      console.log(result);
      document.querySelector('p').innerHTML = result.list.join('<br>')
    }).catch(error => {
      console.log(error);
      document.querySelector('p').innerHTML = error.message
    })
  </script>
</body>

</html>

Promise - 链式调用

概念:依靠then()方法会返回一个新生成的Promise对象特性,继续串联下一环任务,直到结束。

细节:then()回调函数中的返回值,会影响新生成的Promise对象的最终状态和结果

好处:通过链式调用,解决回调函数嵌套问题。

链式调用解决回调函数地狱:省份------城市------地区查询
html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <div class="a"></div>
  <div class="b"></div>
  <div class="c"></div>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script>
    let pname = ''
    const p = axios({ url: 'http://hmajax.itheima.net/api/province' }).then(result => {
      pname = result.data.list[0]
      document.querySelector('.a').innerHTML = pname
      return axios({ url: 'http://hmajax.itheima.net/api/city', params: { pname } })
    }).then(result => {
      const cname = result.data.list[0]
      document.querySelector('.b').innerHTML = cname
      return axios({ url: 'http://hmajax.itheima.net/api/area', params: { pname, cname } })
    }).then(result => {
      const areaName = result.data.list[0]
      document.querySelector('.c').innerHTML = areaName
    })
  </script>
</body>

</html>

Promise.all 静态方法

概念:合并多个Promise对象,等待所有同时成功完成(或某一个失败),做后续逻辑。

需求:当需要同一时间显示多个请求时,就需要把多请求合并。

语法:const p = Promise.all([对象1, 对象2, ...])

async函数和await关键字

定义:asyn和await关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用Promise。

概念:在async函数内,使用await关键字取代then函数,等待获取Promise对象成功状态的结果值。

使用async函数和await关键字解决回调函数地狱

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <div class="a"></div>
  <div class="b"></div>
  <div class="c"></div>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script>
    async function getData() {
      const pobj = await axios({ url: 'http://hmajax.itheima.net/api/province' })
      const pname = pobj.data.list[0]
      const cobj = await axios({ url: 'http://hmajax.itheima.net/api/city', params: { pname } })
      const cname = cobj.data.list[0]
      const aobj = await axios({ url: 'http://hmajax.itheima.net/api/area', params: { pname, cname } })
      const areaName = aobj.data.list[0]

      document.querySelector('.a').innerHTML = pname
      document.querySelector('.b').innerHTML = cname
      document.querySelector('.c').innerHTML = areaName
    }
    getData()
  </script>
</body>

</html>

async函数和await关键字的错误捕获

使用try...catch语句标记要尝试捕获的语句块,并指定一个出现异常时抛出的响应。

语法:

js 复制代码
try {
    // 要执行的代码
} catch(error) {
    // error接收的是错误信息
    // try里代码,如果有错误,直接进入这里执行
}
js 复制代码
    async function getData() {
      try {
        const pobj = await axios({ url: 'http://hmajax.itheima.net/api/province' })
        const pname = pobj.data.list[0]
        const cobj = await axios({ url: 'http://hmajax.itheima.net/api/city', params: { pname } })
        const cname = cobj.data.list[0]
        const aobj = await axios({ url: 'http://hmajax.itheima.net/api/area', params: { pname, cname } })
        const areaName = aobj.data.list[0]

        document.querySelector('.a').innerHTML = pname
        document.querySelector('.b').innerHTML = cname
        document.querySelector('.c').innerHTML = areaName
      } catch (error) {
        console.dir(error)
      }
    }
    getData()
相关推荐
时光追逐者17 分钟前
MongoDB从入门到实战之MongoDB快速入门(附带学习路线图)
数据库·学习·mongodb
一弓虽22 分钟前
SpringBoot 学习
java·spring boot·后端·学习
晓数1 小时前
【硬核干货】JetBrains AI Assistant 干货笔记
人工智能·笔记·jetbrains·ai assistant
我的golang之路果然有问题2 小时前
速成GO访问sql,个人笔记
经验分享·笔记·后端·sql·golang·go·database
genggeng不会代码2 小时前
用于协同显著目标检测的小组协作学习 2021 GCoNet(总结)
学习
lwewan2 小时前
26考研——存储系统(3)
c语言·笔记·考研
搞机小能手2 小时前
六个能够白嫖学习资料的网站
笔记·学习·分类
nongcunqq3 小时前
爬虫练习 js 逆向
笔记·爬虫
汐汐咯3 小时前
终端运行java出现???
笔记
The_cute_cat5 小时前
25.4.22学习总结
学习