XMLHttpRequest2 的新特性

1. XMLHttpRequest2 的新功能

  1. 可以设置HITP请求的时限
  2. 可以使用FormData对象管理表单数据
  3. 可以上传文件
  4. 可以获得数据传输的进度信息

1. 设置 HTTP 请求时限

有时,Ajax 操作很耗时,而且无法预知要花多少时间。如果网速很慢,用户可能要等很久。新版本的XMLHttpRequest对象,增加了timeout属性,可以设置HTTP请求的时限:

xhr.timeout = 3000

上面的语句,将最长等待时间设为3000毫秒。过了这个时限,就自动停止HTTP请求。与之配套的还有一个 timeout 事件,用来指定回调函数 :

xhr.ontimeout = function (event) {

          alert('请求超时了')

}

代码示例 :

<script>
    let xhr = new XMLHttpRequest()
    // 设置 超时时间 (以毫秒为单位)
    xhr.timeout = 30
    // 设置超时以后的回调函数
    xhr.ontimeout = function () {
      console.log('超时了')
    }
    xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks')
    xhr.send()

    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4 && xhr.status === 200) {
        console.log(xhr.responseText);
      }
    }
  </script>

 

2. 使用FormData对象管理表单数据

Ajax 操作往往用来提交表单数据. 为了方便表单处理数据, HTML5 新增了一个 FormData 对象, 可以模拟表单操作 :

 

 代码示例 :

<script>
    // 1. 创建 FormData 实例
    let fd = new FormData()
    fd.append('uname', 'zs')
    fd.append('upew', 'ls')
    let xhr = new XMLHttpRequest()
    xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata')
    xhr.send(fd)
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4 && xhr.status === 200) {
        console.log(JSON.parse(xhr.responseText));
      }
    }
  </script>

FormData对象也可以来获取网页表单里的值, 示例代码如下 :

 

 代码示例 : (重要)

<form id="form1">
    <!-- autocapitalize="off" 用户名关闭首字母大写 -->
    <input type="text" name="uname" autocapitalize="off">
    <input type="password" name="upwd">
    <button type="submit">提交</button>
  </form>

  <script>
    let form = document.querySelector('#form1');
    form.addEventListener('submit', function (e) {
      e.preventDefault()
      let fd = new FormData(form)
      let xhr = new XMLHttpRequest()
      xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata')
      xhr.send(fd)
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
          console.log(JSON.parse(xhr.responseText));
        }
      }
    })
  </script>

3. 上传文件

新版 XMLHttpRequest 对象, 不仅可以发送文本信息, 还可以上传文件.

实现步骤 :

  1. 定义 UL 结构
  2. 验证是否选择了文件
  3. 向 FormData 中追加文件
  4. 使用 xhr 发起上传文件的请求
  5. 监听 onreadystatechange 事件

1. 定义 UL 结构 

 

 2. 验证是否选择了文件

 

 3. 向 FormData 中追加文件

 

 4. xhr 发起上传文件的请求

 

 5. 监听 onreadystatechange 事件

 

 代码示例 :

<body>
  <!-- 1. 文件选框 -->
  <input type="file" id="file1">
  <!-- 2. 上传文件的按钮 -->
  <button id="btnUpload">上传图片</button>
  <br />
  <!-- 3. img 标签, 来显示上传成功以后的图片 -->
  <img src="" alt="" id="img" width="800">

  <script>
    let btnUpload = document.querySelector('#btnUpload')
    btnUpload.addEventListener('click', function () {
      // .files 查看文件是否被选中   files 获取到选择的文件列表
      let files = document.querySelector('#file1').files
      if (files.length <= 0) {
        return alert('请选择要上传的文件')
      }
      let fd = new FormData();
      // 将用户选择的文件添加到 FormData 中
      // 代表 avatar 头像的意思
      fd.append('avatar', files[0])

      let xhr = new XMLHttpRequest()
      xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar')
      xhr.send(fd)
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
          let data = JSON.parse(xhr.responseText)
          if (data.status === 200) {
            // 上传文件
            document.querySelector('#img').src = 'http://www.liulongbin.top:3006' + data.url
          } else {
            console.log(data.message);
          }
        }
      }
    })
  </script>
</body>

 

4. 显示文件上传的进度

新版本的XMLHttpRequest对象中,可以通过监听xhr.upload.onprogress事件,来获取到文件的上传进度。语法格式如下 :

 

代码示例 :

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="js/bootstrap.min.css">
  <script src="js/jquery-3.6.0.js"></script>
</head>
<body>
  <!-- 1. 文件选框 -->
  <input type="file" id="file1">
  <!-- 2. 上传文件的按钮 -->
  <button id="btnUpload">上传</button>
  <!-- bootstrap 中的进度条 -->
  <div class="progress" style="width: 500px; margin: 15px;">
    <div class="progress-bar progress-bar-striped active" style="width: 0%" id="percent">
      0%
    </div>
  </div>
  <br />
  <!-- 3. img 标签, 来显示上传成功以后的图片 -->
  <img src="" alt="" id="img" width="800">

  <script>
    let btnUpload = document.querySelector('#btnUpload')
    btnUpload.addEventListener('click', function () {
      // .files 查看文件是否被选中   files 获取到选择的文件列表
      let files = document.querySelector('#file1').files
      if (files.length <= 0) {
        return alert('请选择要上传的文件')
      }
      let fd = new FormData();
      // 将用户选择的文件添加到 FormData 中
      // 代表 avatar 头像的意思
      fd.append('avatar', files[0])

      let xhr = new XMLHttpRequest()

      // 监听文件上传的进度
      xhr.upload.onprogress = function (e) {
        if (e.lengthComputable) {
          // 计算出上传的进度
          let procentComplete = Math.ceil((e.loaded / e.total) * 100)
          console.log(procentComplete);
          // 动态设置进度条
          $('#percent').attr('style', 'width:' + procentComplete + '%').html(procentComplete + '%')
        }
      }
      xhr.upload.onload = function () {
        // 移除上传中的类  添加上传完成的类样式
        $('#percent').removeClass().addClass('progress-bar progress-bar-success')
      }

      xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar')
      xhr.send(fd)
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
          let data = JSON.parse(xhr.responseText)
          if (data.status === 200) {
            // 上传文件
            document.querySelector('#img').src = 'http://www.liulongbin.top:3006' + data.url
          } else {
            console.log(data.message);
          }
        }
      }
    })
  </script>
</body>
</html>

 

posted @ 2022-05-02 19:57  会前端的洋  阅读(117)  评论(0编辑  收藏  举报