您现在的位置是:首页 >学无止境 >前端学习--Ajax(3) XHR/axios网站首页学无止境

前端学习--Ajax(3) XHR/axios

Michelle209 2023-06-09 20:00:03
简介前端学习--Ajax(3) XHR/axios

一、XMLHttpRequest

1.1 概念

XMLHttpRequest(XHR)是一种用于在客户端和服务器之间发送HTTP请求的JavaScript API。它允许客户端在不重新加载整个页面的情况下向服务器发送请求,并根据服务器的响应更新页面的局部内容。Ajax是基于XHR封装的。

1.2 使用xhr发起get请求

步骤

  1. 创建XHR对象
  2. 调用XHR.open()函数
  3. 调用XHR.send()函数
  4. 监听xhr.onreadystatechange事件
let xhr = new XMLHttpRequest()
xhr.open('GET','http://www.liulongbin.top:3006/api/getbooks')
xhr.send()
xhr.onreadystatechange = function(){
     if(xhr.readyState === 4 && xhr.status === 200){ //固定写法 和数据对象中的status要区分
           console.log(xhr.responseText)
     }
}

 1.3 XHR的readyState属性

0

UNSENTXHR对象已经创建,但是未调用open方法
1OPENEDopen()方法已经被调用
2HEADERS_RECEIVEDsend()方法已经被调用,响应头也被接受
3LOADING数据接收中,此时response属性已经包含部分数据
4DONEAjax请求完成,数据传输完成或失败

1.4 使用XHR发起带参数的get请求

        let xhr = new XMLHttpRequest()
        xhr.open('GET','http://www.liulongbin.top:3006/api/getbooks?id=1')
        //问号后面拼接的是查询字符串,多个参数可以使用&拼接
        xhr.send()
        xhr.onreadystatechange = function(){
            if(xhr.readyState === 4 && xhr.status === 200){ 
                console.log(xhr.responseText)
            }
        }

1.5 查询字符串

get请求携带参数的本质是将参数以查询字符串的形式追加到url的后面

$.get('url',{name:'zs',age:20},function(){})
//等价于
$.get('url?name=zs&age=20',function(){})

1.6 URL编码

如果url中包含中文,要编码成英文

encodeURI()//编码
decodeURI()//解码

一般来说浏览器会自动解析url

1.7 使用xhr发起post请求

步骤

  1. 创建xhr对象
  2. 调用xhr.open()函数
  3. 设置Content-Type属性
  4. 调用xhr.send()函数,指定要发送的数据
  5. 监听xhr.onreadystatechange事件

        let xhr = new XMLHttpRequest()
        xhr.open('POST','http://www.liulongbin.top:3006/api/addbook')
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
        xhr.send('bookname=八月博客&author=august&publisher=洋槐出版社')
        xhr.onreadystatechange = function(){
            if(xhr.readyState === 4 && xhr.status === 200){
                console.log(xhr.responseText)
            }
        }

二、数据交换格式

服务器端与客户端之间的数据传输与交换的格式

前端的两种数据格式是XML与JSON

2.1 XML

Extensible Markup Language 可扩展标记语言,被设计用来传输和存储数据

传输效率低,用JS解析比较麻烦

2.2 JSON

JavaScript Object Notation,Javascript对象表示法,本质是字符串

轻量级的文本数据交换格式,作用上类似于XML

JSON包含对象和数组两种结构

对象结构

{
    key:value,
    key:value,
    ...
}

其中key必须是双引号包裹的英文字符串,value的数据类型可以是数字、字符串、布尔值、null、对象、数组六种类型,不允许出现function和undefined

数组结构

[ ]括起来的内容

数组结构的类型可以是数字、字符串、布尔值、null、对象、数组六种类型

JSON不能写注释,不能用单引号表示字符串,最外层必须是对象或数组格式

作用:在本地与网络传输数据

2.3 JSON与JS中对象的关系

 JSON实际上是一种JavaScript对象的表示方式,本质是字符串

JSON.parse()

JSON转换为JS对象

JSON.stringfy()

JS对象转换为JSON

// JavaScript对象
const person = {
  name: 'Alice',
  age: 30,
  hobbies: ['reading', 'traveling'],
  address: {
    street: '123 Main St',
    city: 'Anytown',
    state: 'CA'
  }
};

// 将JavaScript对象转换为JSON格式字符串
const jsonStr = JSON.stringify(person);
console.log(jsonStr); 
// 输出: {"name":"Alice","age":30,"hobbies":["reading","traveling"],"address":{"street":"123 Main St","city":"Anytown","state":"CA"}}

// 将JSON格式字符串转换回JavaScript对象
const jsonObj = JSON.parse(jsonStr);
console.log(jsonObj);
// 输出: { name: 'Alice', age: 30, hobbies: [ 'reading', 'traveling' ], address: { street: '123 Main St', city: 'Anytown', state: 'CA' } }

三、XMLHttpRequest Level2

3.1 认识

新功能

  • 设置HTTP请求的时限
  • 使用FormData对象管理表单数据
  • 可以上传文件
  • 获取数据传输的进度信息

3.2 设置HTTP请求时限 

        let xhr = new XMLHttpRequest()
        xhr.timeout = 30
        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)
            }
        }

3.3 FormData对象管理表单数据 

        let fd = new FormData()
        //追加数据
        fd.append('uname','zs')
        fd.append('age',18)
        let xhr = new XMLHttpRequest()
        xhr.open('POST','http://www.liulongbin.top:3006/api/formdata')
        xhr.send(fd)

        xhr.onreadystatechange = function(){
            if(xhr.readyState === 4 && xhr.status === 200){
                console.log(xhr.responseText)
                console.log(JSON.parse(xhr.responseText))
            }
        }

3.4 使用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="" class="form1">
        <input type="text" name="uname" autocomplete="off">
        <input type="password" name="pw">
        <button type="submit">提交</button>
    </form>
    <script>
        let form = document.querySelector('.form1')
        let xhr = new XMLHttpRequest()
        form.addEventListener('submit',function(e){
            e.preventDefault()

            let fd = new FormData(form)
            xhr.open('POST','http://www.liulongbin.top:3006/api/formdata')
            xhr.send(fd)
            xhr.onreadystatechange = function(){
            if(xhr.readyState === 4 && xhr.status === 200){
                console.log(xhr.responseText)
            }
        }
        })
    </script>
</body>
</html>

3.5 上传文件

原生JS

<!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="../lib/bootstrap.css">
    <style>
        img{
            width: 300px;
        }
        .progress{
            width: 300px;
            margin: 10px;
        }
    </style>
</head>
<body>
    <input type="file" name="" id="file1">
    <button id="btnUpload">上传文件</button>
    <div class="progress">
        <div class="progress-bar progress-bar-striped active"  style="width: 0%">
          <span class="sr-only"></span>
        </div>
      </div>
    <div>
        <img src="" alt="">
    </div>
    <script>
        const bt1 = document.querySelector('#btnUpload')
        
        let xhr = new XMLHttpRequest()
        let fd = new FormData()
        bt1.addEventListener('click',function(){
            let files = document.querySelector('#file1').files
            if(files.length <= 0)return alert('请选择文件!')
            //将用户上传的文件添加到formdata中
            fd.append('avatar',files[0])
            xhr.open('POST','http://www.liulongbin.top:3006/api/upload/avatar')//文件请求类型必须选择post
            xhr.send(fd)
            xhr.onreadystatechange = function(){
                if(xhr.readyState === 4 && xhr.status === 200){
                    let data = JSON.parse(xhr.responseText)
                    if(data.status === 200){
                        console.log(data)
                        document.querySelector('img').src = 'http://www.liulongbin.top:3006' + data.url
                    }else{
                        alert(data.message)
                    }
                }
            }
            
        })

        const span = document.querySelector('.sr-only')
        const progress = document.querySelector('.progress-bar')
        xhr.upload.onprogress = function(e){
            if(e.lengthComputable){ //布尔值 表示当前上传的资源是否具有可计算的长度
                let percentComplete = Math.ceil((e.loaded / e.total) * 100)
                progress.style.width = `${percentComplete}%`
                span.innerHTML = percentComplete + '%'
            }
        }

    </script>
</body>
</html>

jQuery的方法

<!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>
    <input type="file" name="" id="file1">
    <button id="btnUpload">上传文件</button>
    <div>
        <img id="loading" src="./img/loading.gif" alt="" style="display:none;">
    </div>

    <script src="../lib/jquery.js" ></script>
    <script>
        $(function(){
            //jq实现loading效果
            $(document).ajaxStart(function(){
                $('#loading').show()
            })

            $(document).ajaxStop(function(){
                $('#loading').hide()
            })
                
            
            $('#btnUpload').on('click',function(){
                let files = $('#file1')[0].files
                if(files.length <= 0)return alert('请选择文件后再上传')

                let fd = new FormData()
                fd.append('avatar',files[0])

                $.ajax({ //上传文件必须调用$.ajax
                    method:'POST',
                    url:'http://www.liulongbin.top:3006/api/upload/avatar',
                    data:fd,
                    processData:false, //不对formdata中的url进行编码 原样发送到服务器
                    contentType:false, //使用formdata默认的contentType
                    success:function(res){
                        console.log(res)
                    }
                })
                
            })
        })
    </script>
</body>
</html>

四、axios

比jQuery更加轻量,只专注于网络数据请求

<!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>
    <button id="getbt">GET</button>
    <button id="postbt">POST</button>
    <button id="axios">直接使用axios</button>
    <script src="../lib/jquery.js" ></script>
    <script src="../lib/axios.js"></script>
    <script>
        document.querySelector('#getbt').addEventListener('click',function(){
            const url = 'http://www.liulongbin.top:3006/api/get'
            const obj = {
                name:'zs',
                age:18
            }
            axios.get(url, {params:obj}).then(function(res){
                console.log(res)
            })
        })

        document.querySelector('#postbt').addEventListener('click',function(){
            const url = 'http://www.liulongbin.top:3006/api/post'
            const obj = {
                name:'ls',
                age:20
            }
            axios.post(url, obj).then(function(res){
                console.log(res)
            })
        })

        document.querySelector('#axios').addEventListener('click',function(){
            const url = 'http://www.liulongbin.top:3006/api/get'
            const obj = {
                name:'ww',
                age:22
            }
            axios({
                method:'GET',
                url:url,
                params:obj,
                //data:data, 如果是Post需要将参数放在data   
            }).then(function(res){
                console.log(res)
            })
        })

    </script>
</body>
</html>

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。