草庐IT

ajax - xhr level2新特性 json等众多内容

Heymar-10 2023-03-28 原文

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>0.2
1

我们看到在监听请求状态变化事件里有一个readystate的属性这个属性表示ajax当前请求所处的状态,其中0表示xhr对象以创建,但请求未调用open。1表示已调用open函数。2表示已调用send函数。3表示数据接收中。最后4表示一切请求完成

那么xhr带参的get请求怎么来实现的呢?只需要在open函数的url里面接一个查询字符串即可

xhr.open('get', 'http://www.ssfddaf.com/api?name=%df%fd%gf')

那么什么是查询字符串?

在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>

有关ajax - xhr level2新特性 json等众多内容的更多相关文章

  1. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  2. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  3. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  4. ruby - 查找字符串中的内容类型(数字、日期、时间、字符串等) - 2

    我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s

  5. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

    rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

  6. ruby-on-rails - 如何使用 Rack 接收 JSON 对象 - 2

    我有一个非常简单的RubyRack服务器,例如:app=Proc.newdo|env|req=Rack::Request.new(env).paramspreq.inspect[200,{'Content-Type'=>'text/plain'},['Somebody']]endRack::Handler::Thin.run(app,:Port=>4001,:threaded=>true)每当我使用JSON对象向服务器发送POSTHTTP请求时:{"session":{"accountId":String,"callId":String,"from":Object,"headers":

  7. ruby - 用 YAML.load 解析 json 安全吗? - 2

    我正在使用ruby2.1.0我有一个json文件。例如:test.json{"item":[{"apple":1},{"banana":2}]}用YAML.load加载这个文件安全吗?YAML.load(File.read('test.json'))我正在尝试加载一个json或yaml格式的文件。 最佳答案 YAML可以加载JSONYAML.load('{"something":"test","other":4}')=>{"something"=>"test","other"=>4}JSON将无法加载YAML。JSON.load("

  8. ruby - 如何使用 Selenium Webdriver 根据 div 的内容执行操作? - 2

    我有一个使用SeleniumWebdriver和Nokogiri的Ruby应用程序。我想选择一个类,然后对于那个类对应的每个div,我想根据div的内容执行一个Action。例如,我正在解析以下页面:https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=puppies这是一个搜索结果页面,我正在寻找描述中包含“Adoption”一词的第一个结果。因此机器人应该寻找带有className:"result"的div,对于每个检查它的.descriptiondiv是否包含单词“adoption

  9. jquery - 如何将 AJAX 变量从 jQuery 传递到他们的 Controller ? - 2

    我有一个电子邮件表格。但是我正在制作一个测试电子邮件表单,用户可以在其中添加一个唯一的电子邮件,并让电子邮件测试将其发送到该特定电子邮件。为了简单起见,我决定让测试电子邮件通过ajax执行,并将整个内容粘贴到另一个电子邮件表单中。我不知道如何将变量从我的HAML发送到我的Controllernew.html.haml-form_tagadmin_email_blast_pathdoSubject%br=text_field_tag'subject',:class=>"mass_email_subject"%brBody%br=text_area_tag'message','',:nam

  10. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

随机推荐