AJAX 学习笔记(Day3)

「写在前面」

本文为黑马程序员 AJAX 教程的学习笔记。本着自己学习、分享他人的态度,分享学习笔记,希望能对大家有所帮助。推荐先按顺序阅读往期内容:
1. AJAX 学习笔记(Day1)


目录

  • 3 AJAX 原理
    • 3.1 XMLHttpRequest
    • 3.2 Promise
    • 3.3 封装简易版 axios
    • 3.4 案例 - 天气预报

3 AJAX 原理

3.1 XMLHttpRequest

P33:https://www.bilibili.com/video/BV1MN411y7pw?p=33

什么是 XMLHttpRequest:

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

使用 XMLHttpRequest 步骤:

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

XMLHttpRequest - 查询参数

P34:https://www.bilibili.com/video/BV1MN411y7pw?p=34

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

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

案例:使用XHR携带查询参数,展示某个省下属的城市列表

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

案例:地区查询

P35:https://www.bilibili.com/video/BV1MN411y7pw?p=35

XMLHttpRequest - 数据提交

P36:https://www.bilibili.com/video/BV1MN411y7pw?p=36

步骤和语法:

  1. 没有 axios 了,我们需要自己设置请求头 Content-Type:application/json,来告诉服务器端,我们发过去的内容类型是 JSON 字符串,让他转成对应数据结构取值使用

  2. 没有 axios 了,我们前端要传递的请求体数据,也没人帮我把 JS 对象转成 JSON 字符串了,需要我们自己转换

  3. 原生 XHR 需要在 send 方法调用时,传入请求体携带

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

    // 1. 告诉服务器,我传递的内容类型,是 JSON 字符串
    xhr.setRequestHeader('Content-Type', 'application/json')
    // 2. 准备数据并转成 JSON 字符串
    const user = { username: 'itheima007', password: '7654321' }
    const userStr = JSON.stringify(user)
    // 3. 发送请求体数据
    xhr.send(userStr)

3.2 Promise

P37:https://www.bilibili.com/video/BV1MN411y7pw?p=37

什么是 Promise ?

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

Promise 的好处?

  • 逻辑更清晰(成功或失败会关联后续的处理函数)
  • 了解 axios 函数内部运作的机制
  • 能解决回调函数地狱问题

语法:

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

Promise - 三种状态

P38:https://www.bilibili.com/video/BV1MN411y7pw?p=38

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

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

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

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

P39:https://www.bilibili.com/video/BV1MN411y7pw?p=39

3.3 封装简易版 axios

封装_简易axios_获取省份列表

P40:https://www.bilibili.com/video/BV1MN411y7pw?p=40

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

/**
 * 目标:封装_简易axios函数_获取省份列表
 *  1. 定义myAxios函数,接收配置对象,返回Promise对象
 *  2. 发起XHR请求,默认请求方法为GET
 *  3. 调用成功/失败的处理程序
 *  4. 使用myAxios函数,获取省份列表展示
*/
// 1. 定义myAxios函数,接收配置对象,返回Promise对象
function myAxios(config) {
  return new Promise((resolve, reject) => {
    // 2. 发起XHR请求,默认请求方法为GET
    const xhr = new XMLHttpRequest()
    xhr.open(config.method || 'GET', config.url)
    xhr.addEventListener('loadend', () => {
      // 3. 调用成功/失败的处理程序
      if (xhr.status >= 200 && xhr.status < 300) {
        resolve(JSON.parse(xhr.response))
      } else {
        reject(new Error(xhr.response))
      }
    })
    xhr.send()
  })
}

// 4. 使用myAxios函数,获取省份列表展示
myAxios({
  url: 'http://hmajax.itheima.net/api/province'
}).then(result => {
  console.log(result)
  document.querySelector('.my-p').innerHTML = result.list.join('<br>')
}).catch(error => {
  console.log(error)
  document.querySelector('.my-p').innerHTML = error.message
})

封装_简易axios_获取地区列表

P41:https://www.bilibili.com/video/BV1MN411y7pw?p=41

需求:修改 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()
  })
}

// 3. 使用myAxios函数,获取地区列表
myAxios({
  url: 'http://hmajax.itheima.net/api/area',
  params: {
    pname: '辽宁省',
    cname: '大连市'
  }
}).then(result => {
  console.log(result)
  document.querySelector('.my-p').innerHTML = result.list.join('<br>')
})

封装_简易axios_注册用户

P42:https://www.bilibili.com/video/BV1MN411y7pw?p=42

需求:修改 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) {
      // 2. 转换数据类型,在send中发送
      const jsonStr = JSON.stringify(config.data)
      xhr.setRequestHeader('Content-Type', 'application/json')
      xhr.send(jsonStr)
    } else {
      // 如果没有请求体数据,正常的发起请求
      xhr.send()
    }
  })
}

document.querySelector('.reg-btn').addEventListener('click', () => {
  // 3. 使用myAxios函数,完成注册用户
  myAxios({
    url: 'http://hmajax.itheima.net/api/register',
    method: 'POST',
    data: {
      username: 'itheima999',
      password: '666666'
    }
  }).then(result => {
    console.log(result)
  }).catch(error => {
    console.dir(error)
  })
})

3.4 案例 - 天气预报

P43:https://www.bilibili.com/video/BV1MN411y7pw?p=43

P44:https://www.bilibili.com/video/BV1MN411y7pw?p=44
P45:https://www.bilibili.com/video/BV1MN411y7pw?p=45
P46:https://www.bilibili.com/video/BV1MN411y7pw?p=46

「结束」

本文由mdnice多平台发布

相关推荐
Dread_lxy20 分钟前
vue 依赖注入(Provide、Inject )和混入(mixins)
前端·javascript·vue.js
奔跑草-1 小时前
【前端】深入浅出 - TypeScript 的详细讲解
前端·javascript·react.js·typescript
羡与1 小时前
echarts-gl 3D柱状图配置
前端·javascript·echarts
前端郭德纲2 小时前
浏览器是加载ES6模块的?
javascript·算法
JerryXZR2 小时前
JavaScript核心编程 - 原型链 作用域 与 执行上下文
开发语言·javascript·原型模式
帅帅哥的兜兜2 小时前
CSS:导航栏三角箭头
javascript·css3
渗透测试老鸟-九青2 小时前
通过投毒Bingbot索引挖掘必应中的存储型XSS
服务器·前端·javascript·安全·web安全·缓存·xss
龙猫蓝图2 小时前
vue el-date-picker 日期选择器禁用失效问题
前端·javascript·vue.js
夜色呦2 小时前
掌握ECMAScript模块化:构建高效JavaScript应用
前端·javascript·ecmascript
peachSoda72 小时前
随手记:简单实现纯前端文件导出(XLSX)
前端·javascript·vue.js