什么是xhr?XMLHttpRequest的基本使用及xhr Level2的新特性详解及案例
目录
一、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()函数 → 设置Content-Type属性 → 调用xhr.send()函数 → 监听xhr.onreadyStatechange事件
1、创建xhr对象
var xhr = new XMLHttpRequest()
2、调用xhr.open()函数
xhr.open(‘请求方式’,‘请求地址’)
xhr.open('post','https://blog.csdn.net');
3、设置Content-Type属性(固定写法)
xhr.setRequestHeader('Content-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请求必然处于以下状态中的一个
值 | 状态 | 描述 |
---|---|---|
0 | UNSENT | xhr对象已被创建,但尚未调用open()方法 |
1 | OPENED | open()方法已被调用 |
2 | HEADERS_RECEIVED | send()方法已被调用,响应头已被接收 |
3 | LOADING | 数据接收中,此时response属性中已经包含部分数据 |
4 | DONE | Ajax请求完成,这意味着数据传输已经彻底完成或失败 |
五、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>
最终效果
更多推荐
所有评论(0)