目录
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()来处理




















