XMLHttpRequest2 的新特性
1. XMLHttpRequest2 的新功能
- 可以设置HITP请求的时限
- 可以使用FormData对象管理表单数据
- 可以上传文件
- 可以获得数据传输的进度信息
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 对象, 不仅可以发送文本信息, 还可以上传文件.
实现步骤 :
- 定义 UL 结构
- 验证是否选择了文件
- 向 FormData 中追加文件
- 使用 xhr 发起上传文件的请求
- 监听 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>