目录
1 设置HTTP的请求时限
2 Formdata对象
2.1 简单使用
2.2 Formdata直接获取表单数据
2.3 上传文件
2.4 上传文件的进度
3 定义API根路径
4 请求出错
上面我们用的都是旧版的XMLHttpRequest,旧版有两个缺点
- 无法上传文件
- 没有传送数据的进度信息
XMLHttpRequest Level2 是 XMLHttpRequest 的升级版(随着HTML5一起更新,在2014年10月28日完成更新,如果浏览器支持HTML5大概率也支持XMLHttpRequest的Level2),继承了老版本的所有用法且使用方式相同,有下面这些新的功能
- 设置HTTP请求的时限
- 使用FormData对象管理表单数据
- 可以上传文件
- 可以获得数据传输的进度信息
1 设置HTTP的请求时限
请求时限的属性名称是timeout,过了这个时间还没有请求完毕就中断这次请求
- 单位为毫秒
可以配套使用timeout事件,可以设置中止之后干一点儿什么
我们给一个极短的时间测试一下,比如给3ms
3ms内没有完成请求,请求就中断了自然也没有之后的响应结果。中断后触发了timeout事件,执行了timeout中的函数
在服务端虽然请求中断了,但状态码依然是200
2 Formdata对象
2.1 简单使用
Formdata对象可以更便捷的传输数据,我们简单用一下
上面这个例子中,如果使用FormData发送就不要再使用setRequestHeader()加请求头了,不然会报错
2.2 Formdata直接获取表单数据
- e.preventDefault()是取消默认提交行为
点击提交后得到结果
2.3 上传文件
后端
上传后会保存在代码同级目录下的upload_file,目前我还没上传,文件夹是空的
前端
使用input.files就可以接到选择的文件,files是一个数组一会儿我们打印出来看一下
如果数组元素<=0就是没选择文件,会提示你选择要上传的文件并中止函数
使用files[0]拿到文件加入的FormData对象中
之后直接把FormData对象传上去就行
打开后选择AJAX.jpg
上传之后在文件夹中得到了这张图
2.4 上传文件的进度
<!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>
<style>
section {
width:300px;
height:20px;
padding:2px;
margin-top:20px;
border:3px solid red;
}
div {
width:0px;
height:100%;
background-color: red;
}
</style>
</head>
<body>
<input type="file">
<button>上传文件</button>
<section>
<div></div>
</section>
<span>0%</span>
</body>
<script>
btn = document.querySelector('button')
input = document.querySelector('input')
div = document.querySelector('div')
span = document.querySelector('span')
btn.addEventListener('click',function() {
files = input.files
console.log(files)
if (files.length <= 0) {
return alert('请选择要上传的文件')
}
FormData_obj = new FormData()
FormData_obj.append('file',files[0])
xhr = new XMLHttpRequest()
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
percentComplate = (e.loaded/e.total)*100 - 1
span.innerHTML = percentComplate + '%'
div.style.width = percentComplate + '%'
}
}
xhr.open('POST','http://127.0.0.1:5000/upload')
xhr.send(FormData_obj)
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText)
span.innerHTML = '100%'
div.style.width = '100%'
}
}
})
</script>
</html>
xhr.upload.onprogress的书写位置在创建xhr对象后,xhr.open()前
使用xhr.upload.onprogress事件获取文件的上传进度,该事件的事件对象中我们用到三个属性
- e.lengthComputable 这个值是一个布尔值,如果长度可以计算就返回true,不可计算就返回false
- e.loaded 加载的字节大小
- e.total 文件的总字节大小
我们上传一个看一下,我这里有一个较大的数据集
点击上传文件时进度条会涨,底下的数值也会涨
直到最后100%
这里我将上传进度-1,因为在我的后端上传后还有保存,在其他的后端中上传后肯定也会有其他的操作,所以我等上传有响应后再将其置为100%,这样看起来比较舒服
bootstrap中有样式还不错的进度条,开发的时候可以使用一下 进度条(Progress) · Bootstrap v5 中文文档 v5.1 | Bootstrap 中文网
3 定义API根路径
如果仅仅是根路径的问题,我比较喜欢定义一个全局变量,然后每一次请求的时候都去拼接一下
4 请求出错
像是跨域或断网这种问题都会出现请求出错的问题,我们可以使用xhr.onerror()来捕获错误
比如在我们验证token的时候,当token不对的时候就会出现跨域问题,我们可以使用xhr.onerror()来处理