XMLHttpRequest 新特性:获取进度信息、上传文件、请求时限、表单数据收集FormData
一、数据收集FormData
1. 在没有表单的情况下收集数据
(1)先创建实例对象
var fd = new FormData()
(2)将数据添加进去
fd.append('name', '张三')
fd.append('age', '24')
注意事项:
- fd对象打印出来是 空值
- 要想看到fd对象里面的数据,需要通过 for…in 遍历的方式
- 只能用在 post 请求中
- 不需要设置请求头
(3)通过ajax发送数据
var xhr = new XMLHttpRequest()
xhr.open('post', url)
// 不用设置请求头
xhr.send(fd)
xhr.onreadystatechange = function () {
if(xhr.readystate === 4 && xhr.status === 200){
console.log(xhr.responseText)
}
}
2. 有表单的情况下收集数据
<form action="" id="form">
<input type="text" name="bookname">
<input type="text" name="author">
<input type="text" name="publisher">
<button type="submit">提交</button>
</form>
var form = document.querySelect('#form')
// 1.给form表单注册监听提交事件
form.addEventListener('submit', function (e) {
// 2.阻止默认提交行为
e.preventDefault()
// 3.收集数据:直接传入 form 表单
var fd = new FormData(form)
// 4.使用ajax发送请求
var xhr = new XMLHttpRequest()
xhr.open('post', url)
// 不用设置请求头
xhr.send(fd)
xhr.onreadystatechange = function () {
if(xhr.readystate === 4 && xhr.status === 200){
console.log(xhr.responseText)
}
}
})
二、文件上传
html 结构
<input type="file" id="file">
<button id="upload">上传</button>
<img src="" alt="" width="800">
- 获取文件上传的列表(DOM.files)
var files = document.querySelect('#file').files
// 一定要是原生DOM对象才可以获取到
- 完整的 js 代码:实现上传图片,通过请求获取图片URL,渲染到页面
// 1. 获取元素
var file = document.querySelect('#file')
var upload = document.querySelect('#upload')
// 2. 注册点击事件
upload.addEventListener('click', function(){
// 3. 获取上传文件列表
var files = file.files
// 4. 判断用户是否上传了文件
if (files.length <= 0) {
return alert('请选择文件')
}
// 5. 使用 FormData 收集数据
var fd = new FormData()
fd.append('avatar', files[0])
// 6. 使用 ajax 发送数据
var 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){
// 响应的结果是JSON字符串,所以解析成原来的样子
var result = JSON.parse(xhr.responseText)
// 判断服务器是否保存成功
if(result.status !== 200){
return alert('保存失败')
}
document.querySelect('img').src = 'http://www.liulongbin.top:3006' + result.url
}
}
})
- 使用 jQuery 封装的 $.ajax 发送请求
步骤都差不多,有一点需要注意:需要在 $.ajax 里面添加两行代码
// 如果添加的数据是 FormData 数据对象,需要设置 contentType 和 processData 属性
// 数据不需要编码
contentType: false,
// 数据对象不需要转换成 键值对的字符串格式
processData: false,
三、获取进度信息
xhr.upload.onload = function(){} 表示监听上传进度
xhr.onload = function(){} 表示监听下载进度
xhr.upload.onload = function(e){
// 判断用户是否上传了文件,如果上传了,结果为true
if(e.lengthComputable){
// e.loaded 表示已经上传的进度
// e.total 表示总进度
// 将计算进度的结果存到变量里
var percent = Math.ceil((e.loaded / e.total) * 100) // 计算结果为数字
}
}
利用这个事件,我们就可以在页面上显示进度条了
- 在 html 结构中创建一个进度条
<meter max="100" min="0"></meter>
- 将我们获取到的进度数值 显示到 meter 标签上
将以下代码添加到 xhr.upload.onload 事件里面,计算进度 percent 那一行下面
document.querySelect('meter').value = percent
bootstrap 上面有很多好看的进度条组件,需要的可以自己去查找
- axios 在获取进度信息的时候,已经帮我们封装了一个方法
onUploadProgress: function(e) {
if (e.lengthComputable) {
var percent = parseInt((e.loaded / e.total) * 100);
document.querySelector("meter").value = percent
}
}
四、请求时限
这个就很好理解了:
请求是需要时间的,比如请求某一张高清的图片,可能需要 4s ,但是我们只给他 2s 的时间去请求图片,2s 一过我还没拿到图的话就直接终止请求
// 设置请求时间(单位是 ms)
xhr.timeout = 2000
// 设置回调函数(超过请求时间结束后做什么)
xhr.ontimeout = function(){
return alert('还没好?这么慢?我不要了!!')
}