关于javascript:ajax-xhr-level2新特性-json等众多内容

7次阅读

共计 16520 个字符,预计需要花费 42 分钟才能阅读完成。

1.

明天的内容其实挺多的,咱们缓缓来说。首先第一个是 xhr 的根本应用,什么是 xhr?

XMLHTTPRequest 是浏览器提供的 js 对象,能够申请服务器上的数据资源,包含咱们后面始终用的 jq 外面的三个申请资源的办法都是基于 xhr 来封装的。

那么首先咱们看到 xhr 的 get 申请怎么来实现

首先要创立 xhr 实例通过 new 来实现

而后调用 open 函数,外面值为申请形式以及 url

第三步调用 send 函数

第四步监听 onreadyStateChange 事件在这个事件外面要留神一下申请状态和服务器响应状态的固定写法,还有服务器响应回的数据

<!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>
</head>
<body>
    <script>
        // 1. 创立 xhr 对象
        var xhr = new XMLHttpRequest()
        // 2. 调用 open 函数 决定申请形式和 url
        xhr.open('get', 'http://www.liulongbin.top:3006/api/getbooks')
        // 3. 调用 send 函数
        xhr.send()
        // 4. 监听事件
        xhr.onreadystatechange = function() {
            // 4.1 留神申请状态和服务器响应状态固定写法
            if (xhr.readyState ==4 && xhr.status == 200) {
                // 4.2 获取相应的数据
                console.log(xhr.response);
            }
        }
    </script>
</body>
</html>

1
咱们看到在监听申请状态变动事件里有一个 readystate 的属性这个属性示意 ajax 以后申请所处的状态,其中 0 示意 xhr 对象以创立,但申请未调用 open。1 示意已调用 open 函数。2 示意已调用 send 函数。3 示意数据接管中。最初 4 示意所有申请实现

那么 xhr 带参的 get 申请怎么来实现的呢?只须要在 open 函数的 url 外面接一个查问字符串即可

xhr.open(‘get’, ‘http://www.ssfddaf.com/api?na…’)

那么什么是查问字符串?

在 url 开端加上?参数 = 值多个参数间用 & 来连贯这就是查问字符串,无论是 jQuery 的三个申请形式还是 xhr 指定的参数其本质都是在 url 后带查问字符串

这里还要理解一个点 url 编码与解码

url 中只容许出线英文不容许中文等其余语种,所以他就会把除英文外其余语种转换为 % 结尾带两个字符的款式来代替

编码 encodeURI(‘ 中文;) 解码 decodeURI(% 的字符)三组 % 示意一个中文

2.

接下来咱们看到 xhr 怎么发动 post 申请

第一步创建对象

第二部 open 函数把申请形式改为 post

第三步设置 content-type 这是一个固定写法

xhr.setRequestHeader(‘content-type’,‘application/x-www-form-urlencoded’)

第四步调用 send 函数 post 的参数在这里增加以查问字符串的形式增加进来

第五步监听事件

<!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>
</head>
<body>
    <script>
        // 1. 创立 xhr 对象
        var xhr = new XMLHttpRequest()
        // 2. 调用 open 函数
        xhr.open('post', 'http://www.liulongbin.top:3006/api/addbook')
        // 3. 设置 cententtype
        xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
        // 4. 调用 send 函数
        xhr.send('bookname= 水府传 &author= 我')
        // 5. 监听事件
        xhr.onreadystatechange = function() {if (xhr.readyState == 4 && xhr.status == 200) {console.log(xhr.responseText);
            }
        }
    </script>
</body>
</html>

3.

数据交换格局

即服务器与客户端之间进行数据传输与替换的格局,XML 和 JSON 这两种

XML 咱们用的比拟少,它是可扩大标记语言,跟 html 很类似

JSON

什么事 json,就是 js 对象和数组的字符串表示法,其中实质还是一个字符串它是轻量级文本数据交换格局

它的构造为有两种对象构造和数组构造

对象构造

‘{key:value}’咋一看跟对象很类似,然而首先里面会有引号,其次键值是字符类型必须加双引号

数组构造

【a,a】

要留神的是键值的双引号,json 中不能写正文,不能应用 undefined 和函数作为值

json 和对象互转

obj = JSON.parse(json)(反序列化)

json = JSON.stringify(obj)(序列化)

4.

封装本人的 ajax 函数

①先封装一个解决 data 对象为查问字符串的函数

②封装函数 xhr

③判断不同的申请类型达到不同的形式

这个总之记住一点就是 xhr 调用申请的总体步骤就没得问题

 // 1. 先封装函数解决传进来的参数为查问字符串
        function revolveData(data) {var arr = []
            for (var k in data) {arr[arr.length] = k + '=' + data[k]
            }
            var str = arr.join('&')
            return str
        }
// console.log(revolveData({name : '张三', age : 19}));
// 2。封装主体函数
function ajaxMine(obj) {var xhr = new XMLHttpRequest()
    var str = revolveData(obj.data)
    xhr.onreadystatechange = function() {if (xhr.readyState == 4 && xhr.status == 200) {var res = JSON.parse(xhr.response)
            obj.success(res)
        }
    }
    // 3. 判断不同的申请,做到不同的操作
    if (obj.method.toUpperCase() == 'GET') {xhr.open(obj.method, obj.url + '?' +str)
        xhr.send()} else if (obj.method.toUpperCase() == 'POST') {xhr.open(obj.method, obj.url)
        xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
        xhr.send(str)
    }
}

验证

<!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>
</head>
<body>
    <script src="./ 封装本人的 ajax 函数.js"></script>
    <script>
        /* ajaxMine({
            method : 'get',
            url : 'http://www.liulongbin.top:3006/api/getbooks',
            data : {id : 2},
            success : function(res) {console.log(res);
            }
        }) */
        ajaxMine({
            method : 'post',
            url : 'http://www.liulongbin.top:3006/api/addbook',
            data : {
                bookname : '收首饰',
                author : '东风似旧',
                publisher : '身法'
            },
            success : function(res) {console.log(res);
            }
        }) 
    </script>
</body>
</html>

5.

xhr level2 新个性

在咱们旧版的 xhr 毛病就是不反对文件上传而且没有进度信息只有完没完成

在咱们新版 xhr

反对文件上传,有进度信息,还能够设置 http 时限,还可应用 formdata 对象治理表单数据

接下来我会一一开始 xhr 这四个新个性

5.1

首先第一个设置 Http 时限,也就是在规定工夫如果还没有实现申请工作那么这个申请就失败了

xhr.timeout = 2000

与之对应的还有一个 ontimeout 的事件在超时后会做些什么

<!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>
</head>
<body>
    <script>
        var xhr = new XMLHttpRequest()
        xhr.timeout = 50
        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>
</body>
</html>

5..2

formdata 治理表单

因为咱们 ajax 次要是用来提交表单数据的嘛,所以 H5 就新增了一个 FormData 对象用来模仿表单操作

①新建 formdata 对象

②为 formdata 增加表单项

③创立 xhr

④用 xhr 实现申请

<!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>
</head>
<body>
    <script>
        // 1. 创立 FormData 对象
        var fd = new FormData()
        // 2. 往里面增加表单项
        fd.append('uname', '王五')
        fd.append('age' , 29)
        // 3,创立 xhr 对象
        var xhr = new XMLHttpRequest()
        // 4. 应用 xhr 对象制订申请类型与地址
        xhr.open('post', 'http://www.liulongbin.top:3006/api/formdata')
        // 5. 间接提交,formdata 对象,这与提交网页表单的成果齐全一样
        xhr.send(fd)
        // 6. 验证
        xhr.onreadystatechange = function() {if (xhr.readyState == 4 && xhr.status == 200) {console.log(xhr.responsete);
            }
        }
    </script>
</body>
</html>

formdata 还有一个用法,就是能够用来获取表单的值

<!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>
</head>
<body>
    <form action="">
        <input type="text" name="uname">
        <input type="password" name="pwd">
        <input type="submit" value="提交">
    </form>
    <script>
        var  form = document.querySelector('form')
        form.onsubmit = e => {e.preventDefault()
            var xhr = new XMLHttpRequest()
            var fd = new FormData(form)
            xhr.open('post', 'http://www.liulongbin.top:3006/api/formdata')
            xhr.send(fd)
            xhr.onreadystatechange = () => {if (xhr.readyState == 4 && xhr.status == 200) {console.log(xhr.responseText);
                }
            }
        }
    </script>
</body>
</html>

5.3

上传文件

①定义 UI 构造

②验证是否抉择了文件

③像 formdata 追加文件

④用 xhr 发动上传申请

⑤监听事件

<!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>
</head>
<body>
     <!-- 1. 定义 ui 构造 -->
     <!-- 1.1 文件抉择框 -->
     <input type="file">
     <!-- 1.2 上传按钮 -->
     <input type="submit" value="上传文件">
     <!-- 1.3img 标签 用来显示上传胜利后的图片 -->
     <img src=""alt="">
     <script>
        //  2. 验证是否上传了文件
        var uploadBtn = document.querySelector('input:nth-of-type(2)')
        uploadBtn.addEventListener('click', function() {
            // 2.1 留神这里这个。files 它是一个数组寄存的是文件
            let files = document.querySelector('input:first-child').files
            if (files.length > 0) {
                // 3. 像 formdata 中追加文件
                var fd = new FormData()
                // avator 为头像伪装这里是上传的头像
                fd.append('avatar', files[0])

                // 4. 应用 xhr 发动上传文件申请
                var xhr = new XMLHttpRequest()
                xhr.open('post', 'http://www.liulongbin.top:3006/api/upload/avatar')
                xhr.send(fd)
                // 5. 监听事件
                xhr.onreadystatechange = () => {if (xhr.readyState == 4 && xhr.status == 200) {// console.log(xhr.responseText);
                        let imgData = JSON.parse(xhr.responseText)
                        if (imgData.status == 200) {document.querySelector('img').src = 'http://www.liulongbin.top:3006' + imgData.url
                        } else {console.log('上传文件失败');
                        }
                    }
                }
            } else {return alert('请上传文件')
            }
        })
     </script>
</body>
</html>

5.4

显示上传进度

通过 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>
</head>
<body>
     <!-- 1. 定义 ui 构造 -->
     <!-- 1.1 文件抉择框 -->
     <input type="file">
     <!-- 1.2 上传按钮 -->
     <input type="submit" value="上传文件">
     <!-- 1.3img 标签 用来显示上传胜利后的图片 -->
     <img src=""alt="">
     <script>
        //  2. 验证是否上传了文件
        var uploadBtn = document.querySelector('input:nth-of-type(2)')
        uploadBtn.addEventListener('click', function() {
            // 2.1 留神这里这个。files 它是一个数组寄存的是文件
            let files = document.querySelector('input:first-child').files
            if (files.length > 0) {
                // 3. 像 formdata 中追加文件
                var fd = new FormData()
                // avator 为头像伪装这里是上传的头像
                fd.append('avatar', files[0])

                // 4. 应用 xhr 发动上传文件申请
                var xhr = new XMLHttpRequest()
                
                // --------------------------------
                // 1. 上传进度监听事件
                xhr.upload.onprogress = e => {
                    // 2. 参数一 e.lengthComputable 是一个布尔值,示意以后上传的资源是否具备可计算的长度要有能力进去
                    if (e.lengthComputable) {
                        // 参数二 e.loaded 已传输的字节
                        // 参数三 e.total 需传输的总字节
                        var percenComplete = Math.ceil((e.loaded / e.total) * 100)
                        console.log(percenComplete);
                    }
                }
                xhr.open('post', 'http://www.liulongbin.top:3006/api/upload/avatar')
                xhr.send(fd)
                // 5. 监听事件
                xhr.onreadystatechange = () => {if (xhr.readyState == 4 && xhr.status == 200) {// console.log(xhr.responseText);
                        let imgData = JSON.parse(xhr.responseText)
                        if (imgData.status == 200) {document.querySelector('img').src = 'http://www.liulongbin.top:3006' + imgData.url
                        } else {console.log('上传文件失败');
                        }
                    }
                }
            } else {return alert('请上传文件')
            }
        })
     </script>
</body>
</html>

晓得了上传进度咱们就能够通过 bootstrap 来一个进度条板的上传进度

<!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="../day01/lib/bootstrap.css">
</head>
<body>
     <!-- 1. 定义 ui 构造 -->
     <!-- 1.1 文件抉择框 -->
     <input type="file">
     <!-- 1.2 上传按钮 -->
     <input type="submit" value="上传文件">
     <!-- 1.3img 标签 用来显示上传胜利后的图片 -->
     <img src=""alt="">

     <!-- 进度条 -->
     <div class="progress" style="width: 500px;">
        <div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 0%;">
          0%
        </div>
      </div>
     <script>
        //  2. 验证是否上传了文件
        var uploadBtn = document.querySelector('input:nth-of-type(2)')
        uploadBtn.addEventListener('click', function() {
            // 2.1 留神这里这个。files 它是一个数组寄存的是文件
            let files = document.querySelector('input:first-child').files
            if (files.length > 0) {
                // 3. 像 formdata 中追加文件
                var fd = new FormData()
                // avator 为头像伪装这里是上传的头像
                fd.append('avatar', files[0])

                // 4. 应用 xhr 发动上传文件申请
                var xhr = new XMLHttpRequest()
                
                // --------------------------------
                // 1. 监听事件
                var program = document.querySelector('.progress-bar')
                xhr.upload.onprogress = e => {
                    // 2. 参数一 e.lengthComputable 是一个布尔值,示意以后上传的资源是否具备可计算的长度要有能力进去
                    if (e.lengthComputable) {
                        // 参数二 e.loaded 已传输的字节
                        // 参数三 e.total 需传输的总字节
                        var percenComplete = Math.ceil((e.loaded / e.total) * 100)
                        // console.log(percenComplete);
                        program.style.width = percenComplete + '%'
                        program.innerText = '%' + percenComplete 
                    }
                }
                xhr.open('post', 'http://www.liulongbin.top:3006/api/upload/avatar')
                xhr.send(fd)
                // 5. 监听事件
                xhr.onreadystatechange = () => {if (xhr.readyState == 4 && xhr.status == 200) {// console.log(xhr.responseText);
                        let imgData = JSON.parse(xhr.responseText)
                        if (imgData.status == 200) {document.querySelector('img').src = 'http://www.liulongbin.top:3006' + imgData.url
                        } else {console.log('上传文件失败');
                        }
                    }
                }
            } else {return alert('请上传文件')
            }
        })
     </script>
</body>
</html>

最初欠缺上传胜利的进度条

<!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="../day01/lib/bootstrap.css">
</head>
<body>
     <!-- 1. 定义 ui 构造 -->
     <!-- 1.1 文件抉择框 -->
     <input type="file">
     <!-- 1.2 上传按钮 -->
     <input type="submit" value="上传文件">
     <!-- 1.3img 标签 用来显示上传胜利后的图片 -->
     <img src=""alt="">

     <!-- 进度条 -->
     <div class="progress" style="width: 500px;">
        <div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 0%;">
          0%
        </div>
      </div>
     <script>
        //  2. 验证是否上传了文件
        var uploadBtn = document.querySelector('input:nth-of-type(2)')
        uploadBtn.addEventListener('click', function() {
            // 2.1 留神这里这个。files 它是一个数组寄存的是文件
            let files = document.querySelector('input:first-child').files
            if (files.length > 0) {
                // 3. 像 formdata 中追加文件
                var fd = new FormData()
                // avator 为头像伪装这里是上传的头像
                fd.append('avatar', files[0])

                // 4. 应用 xhr 发动上传文件申请
                var xhr = new XMLHttpRequest()
                
                // --------------------------------
                // 1. 监听事件
                var program = document.querySelector('.progress-bar')
                xhr.upload.onprogress = e => {
                    // 2. 参数一 e.lengthComputable 是一个布尔值,示意以后上传的资源是否具备可计算的长度要有能力进去
                    if (e.lengthComputable) {
                        // 参数二 e.loaded 已传输的字节
                        // 参数三 e.total 需传输的总字节
                        var percenComplete = Math.ceil((e.loaded / e.total) * 100)
                        // console.log(percenComplete);
                        program.style.width = percenComplete + '%'
                        program.innerText = '%' + percenComplete 
                    }
                }
                // -----------------------------------
                // 2. 上传胜利进度条变动
                xhr.upload.onload = () => {program.className = ''program.className ='progress-bar progress-bar-success'}
                xhr.open('post', 'http://www.liulongbin.top:3006/api/upload/avatar')
                xhr.send(fd)
                // 5. 监听事件
                xhr.onreadystatechange = () => {if (xhr.readyState == 4 && xhr.status == 200) {// console.log(xhr.responseText);
                        let imgData = JSON.parse(xhr.responseText)
                        if (imgData.status == 200) {document.querySelector('img').src = 'http://www.liulongbin.top:3006' + imgData.url
                        } else {console.log('上传文件失败');
                        }
                    }
                }
            } else {return alert('请上传文件')
            }
        })
     </script>
</body>
</html>

6.

jQuery 高级用法

用 jq 来实现文件上传

①定义 ui 构造和后面一样

②验证是否抉择文件

③向 formdata 追加文件

④应用 jq 发动上传申请

⑤jq 实现 loading 成果 两个办法一检测到任何 ajax 开始或失败就会调用

<!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>
</head>
<body>
    <!-- 1. 定义 UI 构造 -->
    <form action="">
        <input type="file" name="file" id="">
    </form>
    <!-- 这里呈现了一点小问题 我在前面打印 res 始终打印不进去而且反正就想数据被清了一下思来想去才晓得是我把 button 放在表单里了所以一点击就会造成默认行为 -->
    <button type="submit"> 上传图片 </button>
    <img style="display: none;" src="../../../../HTML/04- 阶段四 前后端交互 / 第四阶段:前后端交互阶段材料新 /ajax 课程材料 /day3(7-12 大节)/code/images/loading.gif" alt="">
    <script src="../day01/lib/jquery.js"></script>
    <script>
        // 5. 这个办法是侦听到所有的 ajax 申请就会开始执行
        $(document).ajaxStart(function() {$('img').show()})
        $(document).ajaxStop(function() {$('img').hide()})
        // 2. 验证是否抉择了文件
        $('button').on('click', function() {
            // 这里须要将 jq 对象转为原生 dom 对象来应用 files 这个属性
            var files = $('input')[0].files
            // console.log(files);
            if (files.length <= 0) {return alert('请抉择文件')
            } else {
                // 3. 向 formdata 追加文件
                var fd = new FormData()
                fd.append('avatar', files[0])
                // 4. 利用 jq 来发动上传申请
                $.ajax({
          method: 'POST',
          url: 'http://www.liulongbin.top:3006/api/upload/avatar',
          data: fd,
          processData: false,
          contentType: false,
          success: function (res) {console.log(res)
          }
        })
            }
        })
    </script>
</body>
</html>

7.

axios

明天的最初一个内容,什么事 axios,专一于网络数据申请的库,相比于原生 xhr 更简略易用,相比于 jq 更轻量化

<!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>
    <script src="./axios.js"></script>
</head>
<body>
    <button> 发动 get 申请 </button>
    <script>
        var btn = document.querySelector('button')
        /* btn.onclick = function() {
            var url = 'http://www.liulongbin.top:3006/api/get'
            var obj = {name : '张三', age : 29}
            axios.get(url, {params: obj}).then(function(res) {console.log(res);
            })
        } */
        btn.onclick = () => {
            axios({
                method : 'get',
                url : 'http://www.liulongbin.top:3006/api/get',
                params : {name : '张三', age : 29}
            }).then(res => console.log(res))
        }
    </script>
</body>
</html>
<!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>
    <script src="./axios.js"></script>
</head>
<body>
    <button> 发动 post 申请 </button>
    <script>
        /* document.querySelector('button').onclick =function() {
            var url = 'http://www.liulongbin.top:3006/api/post'
        var obj = {location : '重庆', address : '江北'}
        axios.post(url, {obj}).then(res => console.log(res))
        } */
        document.querySelector('button').onclick = () => {
            axios({
                method : 'post',
                url : 'http://www.liulongbin.top:3006/api/post',
                data : {name : '张三', age : 29}
            }).then(res => console.log(res))
        }
    </script>
</body>
</html>
<!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="../day01/lib/bootstrap.css">
</head>
<body>
     <!-- 1. 定义 ui 构造 -->
     <!-- 1.1 文件抉择框 -->
     <input type="file">
     <!-- 1.2 上传按钮 -->
     <input type="submit" value="上传文件">
     <!-- 1.3img 标签 用来显示上传胜利后的图片 -->
     <img src=""alt="">

     <!-- 进度条 -->
     <div class="progress" style="width: 500px;">
        <div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 0%;">
          0%
        </div>
      </div>
     <script>
        //  2. 验证是否上传了文件
        var uploadBtn = document.querySelector('input:nth-of-type(2)')
        uploadBtn.addEventListener('click', function() {
            // 2.1 留神这里这个。files 它是一个数组寄存的是文件
            let files = document.querySelector('input:first-child').files
            if (files.length > 0) {
                // 3. 像 formdata 中追加文件
                var fd = new FormData()
                // avator 为头像伪装这里是上传的头像
                fd.append('avatar', files[0])


                // 4. 应用 xhr 发动上传文件申请
                var xhr = new XMLHttpRequest()
                
                // --------------------------------
                // 1. 监听事件
                var program = document.querySelector('.progress-bar')
                xhr.upload.onprogress = e => {
                    // 2. 参数一 e.lengthComputable 是一个布尔值,示意以后上传的资源是否具备可计算的长度要有能力进去
                    if (e.lengthComputable) {
                        // 参数二 e.loaded 已传输的字节
                        // 参数三 e.total 需传输的总字节
                        var percenComplete = Math.ceil((e.loaded / e.total) * 100)
                        // console.log(percenComplete);
                        program.style.width = percenComplete + '%'
                        program.innerText = '%' + percenComplete 
                    }
                }
                // -----------------------------------
                // 2. 上传胜利进度条变动
                xhr.upload.onload = () => {program.className = ''program.className ='progress-bar progress-bar-success'}
                xhr.open('post', 'http://www.liulongbin.top:3006/api/upload/avatar')
                xhr.send(fd)
                // 5. 监听事件
                xhr.onreadystatechange = () => {if (xhr.readyState == 4 && xhr.status == 200) {// console.log(xhr.responseText);
                        let imgData = JSON.parse(xhr.responseText)
                        if (imgData.status == 200) {document.querySelector('img').src = 'http://www.liulongbin.top:3006' + imgData.url
                        } else {console.log('上传文件失败');
                        }
                    }
                }
            } else {return alert('请上传文件')
            }
        })
     </script>
</body>
</html>

正文完
 0