AJAX ---- 3 XMLHttpRequest ◆ Promise

XMLHttpRequest

定义:XMLHttpRequest对象用于服务器交互。通过XMLHttpRequest可以在不刷新页面的情况下请求特定URL,获取数据

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

 步骤:

1. 创建 XMLHttpRequest 对象

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

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

4. 发起请求

    <p></p>
  <script>
    /**
     * 目标:使用XMLHttpRequest对象与服务器通信
     *  1. 创建 XMLHttpRequest 对象
     *  2. 配置请求方法和请求 url 地址
     *  3. 监听 loadend 事件,接收响应结果
     *  4. 发起请求
    */
  //  1. 创建 XMLHttpRequest 对象
  const xhr = new XMLHttpRequest()

  // 2. 配置请求方法和请求 url 地址
  xhr.open('GET', 'http://hmajax.itheima.net/api/province')

  // 3. 监听 loadend 事件,接收响应结果
  xhr.addEventListener('loadend', () => {
    console.log(xhr.response)
    const data = JSON.parse(xhr.response).list.join('<br>')
    // console.log(data.list.join('<br>'))
    document.querySelector('p').innerHTML = data
  })

  // 4. 发起请求
  xhr.send()
  </script>

XMLHttpRequest-查询参数

<body>
  <p class="city-p"></p>
  <script>
    /**
     * 目标:使用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)
    document.querySelector('.city-p').innerHTML = data.list.join('<br>')
   })
   xhr.send()
  </script>
</body>

查询参数对象->查询参数字符串

new URLSearchParams()

转换为URLSearchParams对象,在toString()转换为字符串

// 3.组织查询参数字符串
    const qObj = {
      属性名:属性值
    }

    // 查询参数对象->查询参数字符串
    const paramsObj = new URLSearchParams(qObj)
    const queryString = paramsObj.toString()
    console.log(queryString)

案例_地区查询

<body>
  <div class="container">
    <form id="editForm" class="row">
      <!-- 输入省份名字 -->
      <div class="mb-3 col">
        <label class="form-label">省份名字</label>
        <input type="text" value="北京" name="province" class="form-control province" placeholder="请输入省份名称" />
      </div>
      <!-- 输入城市名字 -->
      <div class="mb-3 col">
        <label class="form-label">城市名字</label>
        <input type="text" value="北京市" name="city" class="form-control city" placeholder="请输入城市名称" />
      </div>
    </form>
    <button type="button" class="btn btn-primary sel-btn">查询</button>
    <br><br>
    <p>地区列表: </p>
    <ul class="list-group">
      <!-- 示例地区 -->
      <li class="list-group-item">东城区</li>
    </ul>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script>
    /**
     * 目标: 根据省份和城市名字, 查询对应的地区列表
    */
  //  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)
      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()
  })
  </script>
</body>

Promise

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

语法:

<script>
    /**
     * 目标:使用Promise管理异步任务
    */
  //  创建Promise对象
   const p = new Promise((resolve, reject) => {
    // Promise对象创建时,这里的代码都会执行
    // 2.执行异步任务
    setTimeout(() => {
      // resolve() => 'fulfilled状态-已兑现' => then()
      resolve('模拟AJAX请求--成功')
      // reject() => 'rejected状态-已拒绝' => then()
      // reject(new Error('模拟AJAX请求--失败'))
    }, 2000)
   })
   console.log(p) // pending 待定
  
  //  3.获取结果
  p.then(result => {
    console.log(result)
  }).catch(error => {
    console.log(error)
  })
  </script>

Promise - 三种状态

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

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

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

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

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

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

封装简易版 axios

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

<body>
  <p class="my-p"></p>
  <script>
    /**
     * 目标:封装_简易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.dir(error)
        document.querySelector('.my-p').innerHTML = error.message
      })
  </script>
</body>

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

<body>
  <p class="my-p"></p>
  <script>
    /**
     * 目标:封装_简易axios函数_获取地区列表
     *  1. 判断有params选项,携带查询参数
     *  2. 使用URLSearchParams转换,并携带到url上
     *  3. 使用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>')
      }).catch(error => {
        console.dir(error)
        document.querySelector('.my-p').innerHTML = error.message
      })
  </script>
</body>

封装_简易axios_注册用户

<body>
  <button class="reg-btn">注册用户</button>
  <script>
    /**
     * 目标:封装_简易axios函数_注册用户
     *  1. 判断有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) {
          // 转换数据类型,在send中发送
          const jsonStr = JSON.stringify(config.data)
          xhr.setRequestHeader('Content-Type', 'application/json')
          xhr.send(jsonStr)
        }else {
          // 如果没有data参数,正常发起请求
          xhr.send()
        }
      })
    }
    
    // 给注册按钮绑定点击事件
    document.querySelector('.reg-btn').addEventListener('click', () => {
      // 3. 使用myAxios函数,完成注册用户
      myAxios({
        url: 'http://hmajax.itheima.net/api/register',
        method: 'POST',
        data: {
          username: 'itheima555',
          password: '1234567'
        }
      }).then(result => {
        console.log(result)
      }).catch(error => {
        console.dir(error)
      })
    })
 </script>
</body>

案例 - 天气预报

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值