当前位置: 首页 > news >正文

什么是xhr?XMLHttpRequest的基本使用及xhr Level2的新特性详解及案例

目录

  • 一、XMLHttpRequest概念
    • 1、定义
    • 2、能否直接使用xhr对象发起Ajax请求
    • 3、什么是Ajax
  • 二、xhr发起GET请求
    • 1、创建xhr对象
    • 2、调用xhr.open()函数
    • 3、调用xhr.send()函数
    • 4、监听xhr.onreadyStatechange事件
    • 5、发送带参数的get请求
  • 三、xhr发起POST请求
    • 1、创建xhr对象
    • 2、调用xhr.open()函数
    • 3、设置Conent-Type属性(固定写法)
    • 4、调用xhr.send()函数
    • 4、监听xhr.onreadyStatechange事件
  • 四、了解xhr的readyState属性
  • 五、XMLHttpRequest Level2的新特性
    • 旧版xhr缺点
    • xhr Level2新功能
    • 1、可以设置HTTP请求的时限
    • 2、可以使用FormData对象管理表单数据
      • ① 提交form表单数据
      • ② 获取网页表单的值
    • 3、 可以上传文件
      • ① 定义UI结构
      • ② 验证用户是否选择了文件
      • ③ 向FormData中追加文件
      • ④ 使用xhr发起上传文件的请求
      • ⑤ 监听onreadyStatechange事件
    • 4、可以获得数据传输的进度信息
  • 六、案例(实现文件带进度条上传)
    • 1、基于Bootstrap绘制进度条效果
    • 2、动态设置进度条
    • 3、监听上传完成的事件
    • 完整代码
    • 最终效果

一、XMLHttpRequest概念

1、定义

XMLHttpRequest(简称xhr),是浏览器提供的JS对象,通过它可以请求到服务器上的数据资源

2、能否直接使用xhr对象发起Ajax请求

可以,但比较麻烦
jQuery中的Ajax函数时基于xhr对象封装出来的。

3、什么是Ajax

Ajax是一种用于创建快速动态网页的技术,在网页中利用XMLHttpRequest对象和服务器进行数据交互的方式

二、xhr发起GET请求

步骤:创建xhr对象 → 调用xhr.open()函数 → 调用xhr.send()函数 → 监听xhr.onreadyStatechange事件

1、创建xhr对象

var xhr = new XMLHttpRequest()

2、调用xhr.open()函数

xhr.open(‘请求方式’,‘请求地址’)

xhr.open('get','https://blog.csdn.net/Vest_er/article/details/127216365');

3、调用xhr.send()函数

xhr.send()

4、监听xhr.onreadyStatechange事件

监听xhr对象的请求状态readyState,与服务器响应状态status

xhr.onreadyStatechange = function () {
	// 固定的判断条件
	 if(xhr.readyState) === 4 && xhr.status === 200 {
	 	// 打印服务器响应回来的数据
		console.log(xhr.responseText)
	}
}

5、发送带参数的get请求

通过查询字符串的形式发起带参数请求

xhr.open('get','https://blog.csdn.net/Vest_er?id=02&name=zs');

三、xhr发起POST请求

步骤:创建xhr对象 → 调用xhr.open()函数 → 设置Conent-Type属性 → 调用xhr.send()函数 → 监听xhr.onreadyStatechange事件

1、创建xhr对象

var xhr = new XMLHttpRequest()

2、调用xhr.open()函数

xhr.open(‘请求方式’,‘请求地址’)

xhr.open('post','https://blog.csdn.net');

3、设置Conent-Type属性(固定写法)

xhr.setRequestHeader('Conent-Type','application/x-www-form-urlencoded')

4、调用xhr.send()函数

同时数据以查询字符串的形式,提交给服务器

xhr.send('name=憨瓜&age=3&sex=公猫已绝育')

4、监听xhr.onreadyStatechange事件

监听xhr对象的请求状态readyState,与服务器响应状态status

xhr.onreadyStatechange = function () {
	// 固定的判断条件
	 if(xhr.readyState) === 4 && xhr.status === 200 {
	 	// 打印服务器响应回来的数据
		console.log(xhr.responseText)
	}
}

四、了解xhr的readyState属性

readyState属性用来表示当前Ajax请求所处的状态,每个Ajax请求必然处于以下状态中的一个

状态描述
0UNSENTxhr对象已被创建,但尚未调用open()方法
1OPENEDopen()方法已被调用
2HEADERS_RECEIVEDsend()方法已被调用,响应头已被接收
3LOADING数据接收中,此时response属性中已经包含部分数据
4DONEAjax请求完成,这意味着数据传输已经彻底完成或失败

五、XMLHttpRequest Level2的新特性

Level2代表的是新版的XMLHttpRequest

旧版xhr缺点

① 只支持文本数据的传输,无法用来读取和上传文件
② 传送和接收数据时,没有进度信息,只能提示有没有完成

xhr Level2新功能

1、可以设置HTTP请求的时限

有时Ajax操作很耗时,而且无法预知要等多久。新版xhr对象增加了timeout属性和timeout事件,可以设置http请求时限

timeout属性:设置超时时间;timeout事件:设置超时之后的回调

// 将最长等待时间设置为3秒,超过时限自动地址http请求
xhr.timeout = 3000;

// timeout事件,设置超时之后的回调函数
xhr.ontimeout = function(event) {
	alert('请求超时了!');
}

2、可以使用FormData对象管理表单数据

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

① 提交form表单数据

<script>
    // 1.创建一个FormData对象
    var fd = new FormData();

    // 2.为FormData添加表单项
    fd.append('uname','憨瓜');
    fd.append('upwd','123456');

    // 3.创建xhr对象
    var xhr = new XMLHttpRequest();

    // 4.指定球球类型和URL地址
    xhr.open("POST",'http://www.liulongbin.top:3006/api/formdata');

    // 5.直接提交formdata对象,这与提交网页表单的效果一样
    xhr.send(fd);

    // 监听请求状态改变的事件
    xhr.onreadystatechange = function (){
        if(xhr.readyState == 4 && xhr.status == 200) {
            // JSON字符串转化为JS对象
            var result = JSON.parse(xhr.responseText);
            console.log(result)
        }
    }
</script>

在这里插入图片描述

② 获取网页表单的值

<body>
    <form  id="form">
        <input type="text" name="uname" autocomplete="off">
        <input type="password" name="upwd">
        <button type="submit">提交</button>
    </form>

    <script>
        // 1.获取表单元素
        var form = document.querySelector("#form");

        // 2.监听表单元素的submit事件
        form.addEventListener('submit',function(e){
            e.preventDefault(); // 阻止表单默认行为
            //根据form表单创建FormData对象会自动将表单数据填充到FormData对象中
            var fd = new FormData(form);

            var 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>
</body>

在这里插入图片描述

3、 可以上传文件

实现步骤:定义UI结构 → 验证用户是否选择了文件 → 向FornData中追加文件 → 使用xhr发起上传文件的请求 → 监听onreadyStatechange事件

① 定义UI结构

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

② 验证用户是否选择了文件

// 1.获取上传文件的按钮
var btnUpload = document.querySelector('#btnUpload');
// 2. 为按钮绑定单击事件处理函数
btnUpload.addEventListener('click',function(){
    // 3.获取到选择的文件列表
    var files = document.querySelector("#file1").files;
    if(files.length<=0){
        return alert ('请选择要上传的文件');
    }
})

③ 向FormData中追加文件

// 1.创建formdata对象
var fd = new FormData();
// 2.向formdata中追加文件
fd.append("avatar",files[0])

④ 使用xhr发起上传文件的请求

// 1.创建xhr
var xhr = new XMLHttpRequest();
// 2.创建请求
xhr.open("POST",'http://www.liulongbin.top:3006/api/upload/avator');
// 3.发起请求
xhr.send(fd);

⑤ 监听onreadyStatechange事件

xhr.onreadystatechange = function () {
  if (xhr.readyState === 4 && xhr.status === 200) {
    var 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)
    }
  }
}

4、可以获得数据传输的进度信息

可以通过监听xhr.upload.onprogress事件,来获取文件的上传进度

// 监听xhr.upload的onprogress事件
xhr.upload.onload = function (e) {
	// e.lengthComputable是一个布尔值,表示当前上传的资源是否具有可计算的长度
   if(e.lengthComputable){
   		// e.loaded:已传输的字节;e.total:需传输的总字节
   		var precentComplete = Math.ceil((e.loaded / e.total) *100)
   }
}

六、案例(实现文件带进度条上传)

1、基于Bootstrap绘制进度条效果

Bootstrap进度条地址:https://v3.bootcss.com/components/#progress

 <!-- 引入Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">

<!-- bootstrap 中的进度条 -->
<div class="progress" style="width: 500px; margin: 15px 10px;">
  <div class="progress-bar progress-bar-striped active" style="width: 0%" id="percent">
    0%
  </div>
</div>

2、动态设置进度条

基于jQuery操作DOM,调用attr属性设置style样式

引入jQuery
 <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
 
// 监听文件上传的进度
xhr.upload.onprogress = function (e) {
  if (e.lengthComputable) {
    // 计算出上传的进度
    var procentComplete = Math.ceil((e.loaded / e.total) * 100)
    console.log(procentComplete)
    // 动态设置进度条
    $('#percent').attr('style', 'width: ' + procentComplete + '%;').html(procentComplete + '%')
  }
}

3、监听上传完成的事件

 xhr.upload.onload = function () {
 		// removeClass():移除上传中的类样式;addClass()添加上传完成的类样式
        $('#percent').removeClass().addClass('progress-bar progress-bar-success')
      }

完整代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <!-- 引入bootstrap-->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
  <!-- 引入jQuery -->
  <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>

<body>
  <!-- 1. 文件选择框 -->
  <input type="file" id="file1" />
  <!-- 2. 上传文件的按钮 -->
  <button id="btnUpload">上传文件</button>

  <!-- bootstrap 中的进度条 -->
  <div class="progress" style="width: 500px; margin: 15px 10px;">
    <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>
    // 1. 获取到文件上传按钮
    var btnUpload = document.querySelector('#btnUpload')
    // 2. 为按钮绑定单击事件处理函数
    btnUpload.addEventListener('click', function () {
      // 3. 获取到用户选择的文件列表
      var files = document.querySelector('#file1').files
      if (files.length <= 0) {
        return alert('请选择要上传的文件!')
      }
      var fd = new FormData()
      // 将用户选择的文件,添加到 FormData 中
      fd.append('avatar', files[0])

      var xhr = new XMLHttpRequest()

      // 监听文件上传的进度
      xhr.upload.onprogress = function (e) {
        if (e.lengthComputable) {
          // 计算出上传的进度
          var 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) {
          var 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>

最终效果

在这里插入图片描述

相关文章:

  • VMware-安装 CentOs-Linux 操作系统
  • 【老生谈算法】matlab实现LMS算法的自适应滤波算法源码——自适应滤波
  • Springboot 玩一玩代码混淆,防止反编译代码泄露
  • 【配电网重构】基于matlab负荷平衡的配电网重构【含Matlab源码 2180期】
  • 计算机网络---第二章物理层---通信基础
  • 【JAVA问题解决方案】01.EasyExcel导出数据超过Excel单表上限解决方案
  • 第一个C/C++项目
  • 让人获益匪浅的学习网站
  • C语言——经典200道实例(51-55)
  • 软件测试是干什么的?为什么受就业者的欢迎?
  • SpringMVC执行流程
  • 图片的谱表征
  • 基于Vue+node的图书馆座位预约选座管理系统
  • 用DIV+CSS技术设计的凤阳旅游网站(web前端网页制作课作业)HTML+CSS+JavaScript
  • 【redis】从高并发场景下超卖问题到redis分布式锁
  • 0x05 Python数据分析,Anaconda八斩刀
  • AHK 中 = 和 == 等比较运算符的用法
  • Android单元测试 - 几个重要问题
  • Bytom交易说明(账户管理模式)
  • CSS中外联样式表代表的含义
  • java 多线程基础, 我觉得还是有必要看看的
  • PHP变量
  • SQLServer插入数据
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • 阿里研究院入选中国企业智库系统影响力榜
  • 大整数乘法-表格法
  • 基于Vue2全家桶的移动端AppDEMO实现
  • 【干货分享】dos命令大全
  • const的用法,特别是用在函数前面与后面的区别
  • NLPIR智能语义技术让大数据挖掘更简单
  • ​马来语翻译中文去哪比较好?
  • ​什么是bug?bug的源头在哪里?
  • #宝哥教你#查看jquery绑定的事件函数
  • #前后端分离# 头条发布系统
  • (1)svelte 教程:hello world
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (152)时序收敛--->(02)时序收敛二
  • (173)FPGA约束:单周期时序分析或默认时序分析
  • (4)事件处理——(6)给.ready()回调函数传递一个参数(Passing an argument to the .ready() callback)...
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (笔记自用)LeetCode:快乐数
  • (附源码)小程序 交通违法举报系统 毕业设计 242045
  • (教学思路 C#之类三)方法参数类型(ref、out、parmas)
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (三)elasticsearch 源码之启动流程分析
  • (转)3D模板阴影原理
  • (最新)华为 2024 届秋招-硬件技术工程师-单板硬件开发—机试题—(共12套)(每套四十题)
  • .bat批处理(九):替换带有等号=的字符串的子串
  • .gitignore文件---让git自动忽略指定文件
  • .net Application的目录
  • .Net Winform开发笔记(一)
  • .NET(C#) Internals: as a developer, .net framework in my eyes
  • .NET/C# 中你可以在代码中写多个 Main 函数,然后按需要随时切换
  • .Net面试题4
  • .one4-V-XXXXXXXX勒索病毒数据怎么处理|数据解密恢复