“Ajax&axios:一次前端革命的终极总结“


什么是ajax?

Ajax(Asynchronous Javascript And XML)(异步js和XML),在网页中利用XMLHttpRequest对象和服务器进行数据交互的方式,就是Ajax。

为什么学ajax?

​ 之前所学的技术,只能把网页做得更漂亮,或添加一些动画的效果,但是,ajax能让我们轻松实现网页与服务器之间的数据交互,ajax能够为咱们的网页和服务器之间进行数据传输的功能。

ajax典型应用场景

  • 用户检测: 注册用户时,通过ajax的形式,动态检测用户名是否被占用
  • 搜索提示: 当输入搜索关键字时,通过ajax形式,动态加载搜索提示列表
  • 数据分页显示: 当点击页码值时,通过ajax的形式,根据页码值动态刷新表格的数据
  • 数据的增删查改: 数据的添加、删除、修改、查询操作,都需要通过ajax的形式,来实现数据的交互

1.JQuery中的Ajax

​ 浏览器中提供的XMLHttpRequest用法比较复杂,所以JQuery对XMLHttpRequest进行了封装,提供了一系列Ajax相关函数,极大的降低了ajax的使用难度。

JQuery中发起Ajax请求最常用的三个方法:

  • $.get()
  • $.post()
  • $.ajax()

1.$.get()

​ JQeury中$.get()函数的功能单一,专门用来发送get请求从而将服务器上的资源请求到客户端来进行使用。

// 语法: 
$.get(url,[data],[callback])
  • url: string类型,表示要请求的资源地址
  • data: object类型,请求资源期间需要携带的参数
  • callback: function,请求成功时的回调函数

(1)$.get()发起不带参数的请求

$.get("http://www.xxx.top:3006/api/getbooks", function (res) { 
                    console.log(res)
})
  • res就是服务器返回的数据

(2)$.get()发起带参数的请求

$.get("http://www.xxx.top:3006/api/getbooks", { id: 1 }, function (res){
                    console.log(res)
})

2.$.post()

​ JQeury中$.post()函数的功能单一,专门用来发送post请求,从而向服务器提交数据。

// 语法:
$.post(url,[data],[callback])

$.post()发起提交数据的请求

$.post("http://www.xxx.top:3006/api/getbooks", { 
		bookname: "三国演义", 
		autor: "施耐庵", 
		publisher: "深圳图书出版社" 
		}, function (res) {
                    console.log(res)
})

3.$.ajax()

​ 相比于 . g e t ( ) 和 .get()和 .get().post()函数,JQeury中提供的$.ajax()函数,是一个功能比较综合的函数,它允许我们对ajax请求更详细的配置。

// 语法:
		$.ajax({
            method: '',        
            url: '',         
            data: {},       
            success: function (res) {   
            }
        })
  • method:请求的方式,例如get或者post
  • url:请求的url地址
  • data: 请求要携带的数据
  • success:请求成功之后的回调函

(1)$.ajax()发起get请求

		$.ajax({
            method: 'GET',
           	url: 'http://www.xxx.top:3006/api/getbooks',
            data: { id: 1 },    
            success: function (res) {
            console.log(res)
            }
        })
  • 使用$.ajax()发起get请求时,只需要method属性的值改为’get
  • data是可选参数

(2)$.ajax()发起post请求

		$.ajax({
            method: 'POST',
           	url: 'http://www.xxx.top:3006/api/getbooks',
            data: { 
            bookname: "三国演义",
            autor: "施耐庵", 
            publisher: "深圳图书出版社" 
            },    
            success: function (res) {
            console.log(res)
            }
        })
  • 使用$.ajax()发起post请求时,只需要method属性的值改为’post

2.Ajax

XMLHttpRequest(简称xhr)是浏览器提供的JavaScript对象,通过它,可以请求服务器上的数据资源。

​ 使用Ajax,我们就需要使用到XMLHttpRequest对象。

1.xhr发起get请求

(1).xhr发起不带参数的get请求

		// 1.创建xhr对象
        var xhr = new XMLHttpRequest()
        // 2.调用open()函数
        xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks')
        // 3.调用send()函数
        xhr.send()
        // 4.监听onreadystatechanges事件
        xhr.onreadystatechanges = function () {
            // 判断xhr请求状态和服务器响应状态
            if (xhr.readyState === 4 && xhr.status === 200) {
                // 获取服务器响应的数据
                console.log(xhr.responseText)
            }

        }

(2).xhr发起带参数的get请求

		var xhr = new XMLHttpRequest()
        xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks?id=1')
        xhr.send()
        xhr.onreadystatechanges = function () {
            if (xhr.readyState === 4 && xhr.status === 200) {
                console.log(xhr.responseText)
            }
        }
  • 只需在调用open期间,为url地址指定参数(url地址后面拼接的参数为查询字符串的形式)

扩展:

  • 查询字符串是指在url末尾加上用于向服务器发送信息的字符串(变量)
  • 查询字符串的格式是将英文?放在url的末尾,然后再加上参数=值,多个参数用&符号分隔
  • 通过查询字符串可以将想要发送给服务器的数据添加到url中

​ 无论使用 . g e t ( ) 还是 .get()还是 .get()还是.ajax(),又或者直接使用xhr对象发起的GET请求,当需要携带参数的时候,本质上都是将参数以查询字符串的形式,追加到url地址的后面。

如:

		$.ajax({
            method: 'GET',
            url: 'http://www.liulongbin.top:3006/api/getbooks',
            data: {
                id: 1,
                bookname: '西游记',
            },
            // 等价于url:'url?id=1&..'
            success: function (res) {
                console.log(res)
            }
        })

2.xhr发起post请求

		// 1.创建XMLHttpRequest对象
        const xhr = new XMLHttpRequest()
        // 2.调用open()
        xhr.open('POST', 'http://www.liulongbin.top:3006/api/getbooks')
        // 3.设置Content-Type属性
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
        // 4.调用send()
        xhr.send('bookname=水浒传&author=施耐庵&publisher=上海图书出版社')
        // 5.监听onreadystatechanges事件
        xhr.onreadystatechanges = function () {
            if (xhr.readyState === 4 && xhr.status === 200) {
                console.log(xhr.responseText)
            }
        }
  • 需要在setRequestHeader()中设置Content-Type属性
  • 发起请求时所携带的参数放到send()中

扩展:

(1)在myAjax.js中封装自己的Ajax函数

// 定义resolveDate()来处理data参数
function resovleData(data) {    // 处理data参数: 需要把data对象, 转换为查询字符串的格式

    const arr = []
    for (let k in data) {
        const str = k + '=' + data[k]
        arr.push(str)
    }

    return arr.join('&')
}

function myAjax(options) {

    const xhr = new XMLHttpRequest()
    // 把用户传过来的data参数转换为查询字符串
    const qs = resovleData(options.data)
    // 判断请求方式
    if (options.method.toUpperCase() === 'GET') {
        // 发起GET请求
        xhr.open(options.method, options.url + '?' + qs)
        xhr.send()

    } else if (options.method.toUpperCase() === 'POST') {
        // 发起POST请求
        xhr.open(options.method, options.url)
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
        xhr.send(qs)
    }
    xhr.onreadystatechanges = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
            // 把JSON字符串转换为JS对象
            const result = JSON.parse(xhr.responseText)
            options.success(result)
        }
    }
}

(2)使用自己的ajax

<script src="./myAjax.js"></script>

<script>

        myAjax({
            method: 'GET',
            url: 'http://www.liulongbin.top:3006/api/getbooks',
            data: {
                id: 1
            },
            success: function (res) {
                console.log(res)
            }
        })
</script>

3.url编码与解码

​ url地址中,只允许出现英文相关的字母、标点符号、数字。因此在url地址中不允许出现中文字符等,如果需要url中包含中文这样的字符,则需要对中文字符进行编码(转义)

​ 浏览器提供了url编码与解码的API,分别是: encodeURI()、decodeURI()。

url编码原则:

  • 使用安全字符(英文字符)去表示不安全字符(非英文字符)

1.编码

encodeURI()

const str = '柳州螺蛳粉'
console.log(encodeURI(str))	// // %E6%9F%B3%E5%B7%9E%E8%9E%BA%E8%9B%B3%E7%B2%89

2.解码

decodeURI()

console.log(decodeURI('%E6%9F%B3%E5%B7%9E'))	// 柳州

4.数据交换格式

数据交换格式就是服务器端与客户端之间进行数据传输与交换格式。前端领域中两种经常提到的数据交换格式分别为XML和JSON。

1.XML

XML(EXtensible Markup Language),即扩展标记语言,和HTML类似。

示例:

	<node>
        <to>李四</to>
        <from>张三</from>
        <heading>通知</heading>
        <body>开会</body>
    </node>
  • xml和html虽然都是标记语言,但是两者没有任何关系
  • HTML被设计用来描述网页上的内容,是网页内容载体
  • XML被设计用来传输和存储数据,是数据载体

xml的缺点:

  • 格式臃肿,和数据无关的代码多,体积大,传输效率低
  • 在javascript中解析XML比较麻烦

2.JSON

JSON(JavaScript Object Notation),即JavaScript对象表示法。简单来说就是JavaScript对象和数组的字符串表示法,它使用文本表示一个JS对象或数组的信息,因此JSON本质上是字符串

作用:

  • JSON是一种轻量级的文本数据交换格式,在作用上类似XML,专门用于存储和传输数据。
  • 但是JSON比XML更小、更快、更易解析

(1)JSON的两种结构

对象结构

		{
            "name":"zs",
            "age":20,
            "gender":"男",
            "address":null,
            "hobby":["吃饭","睡觉","打游戏"]
        }
  • key必须是使用英文的双引号包裹的字符串,value的数据类型可以是数组、字符串、布尔值、null、数组、对象6种类型

数组结构

[30,"java",true,null...]
  • 数组结构中的数据类型可以是数字、字符串、布尔值、null,数组,对象6种类型

jSON和JS对象的关系:

JSON是JS对象的字符串表示法,它使用文本表示一个JS对象的信息,本质上是一个字符串,如

// 这是一个对象
var obj = {a:'hello',b:'world'}
// 这是一个JSON字符串,本质上就是字符串
var json = '{"a":"hello","b":"world"}'

(2)JSON和js对象的互转

JSON.parse()

const json = '{"a":"hello","b":"world"}'
const res1 = JSON.parse(json)
console.log(res1)		// {a: 'hello', b: 'world'}
  • JSON字符串转换为JS对象

JSON.stringify()

const obj = { a: 'hello', b: 'world', c: false }
const res2 = JSON.stringify(obj)
console.log(res2, typeof res2)	// {"a":"hello","b":"world","c":false}  string
  • JS对象转换为JSON字符串

扩展:

  • 序列化: 把数据对象转换为字符串的过程,叫做序列化。
  • 调用JSON.stringify()函数的操作就叫JSON序列化
  • 反序列化: 把字符串转换为数据对象的过程,叫反序列化。
  • 调用JSON.parse()函数的操作就叫反序列化

JSON.parse()应用场景:

		// Ajax向服务器发送请求
        const xhr = new XMLHttpRequest()
        xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks')
        xhr.send()
        xhr.onreadystatechanges = function () {
            if (xhr.readyState === 4 && xhr.status === 200) {

                console.log(xhr.responseText)   // 得到的就是JSON字符串
                console.log(typeof xhr.responseText)    // string

                // 将得到的JSON字符串转换为JS对象
                const res = JSON.parse(xhr.responseText)
                console.log(res)
            }
        }

5.XMLHttpRequest Leve2新特性

​ 有时候,Ajax很耗时,而且无法预知要花多少时间。如果网速很慢,用户可能要等很久。新版本的XMLHttpRequest对象,新增了timeout属性,可以设置HTTP请求的时限

1.设置超时时限

		const xhr = new XMLHttpRequest()
        // 设置超时时限(过了这个时限就自动停止HTTP请求)
        xhr.timeout = 3000
        xhr.ontimeout = function (e) {
            alert('请求超时!')
        }
        xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks')
        xhr.send()
        xhr.onreadystatechanges = function () {
            if (xhr.readyState === 4 && xhr.status === 200) {
                console.log(xhr.responeText)
            }
        }
  • 与之配套的还有ontimeout事件,用来指定回调函数

2.FormData对象的使用

		// 1.创建FormData()对象
        const fd = new FormData()
        // 2.调用append()函数,向fd中追加数据 
        fd.append('uname', '张三')
        fd.append('age', 18)

        const xhr = new XMLHttpRequest()
        xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata')
        // 3.直接提交FormData()对象
        xhr.send(fd)
        xhr.onreadystatechanges = function () {
            if (xhr.readyState === 4 && xhr.status === 200) {
                console.log(JSON.parse(xhr.responseText))
            }
        }

3.使用FormData快速获取表单的数据

	<form id="form1">
        <input type="text" name="uname" autocomplete="off">
        <input type="password" name="pswd">
        <button type="submit">提交</button>
    </form>

    <script>
        // 1.通过DOM操作,获取到form表单元素
        const form = document.querySelector('#form1')
        form.addEventListener('submit', function (e) {
            // 阻止表单的默认提交行为
            e.preventDefault()
            // 2.创建FormData对象,快速获取到form表单中的数据
            const fd = new FormData(form)
            const xhr = new XMLHttpRequest()
            xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata')
            // 3.直接提交FormData()对象
            xhr.send(fd)

            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4 && xhr.status === 200) {
                    console.log(JSON.parse(xhr.responseText))
                }
            }
        })
    </script>
  • autocomplete: 设置为off后,阻止表单自动填充

4.上传文件

	<!-- 1.定义UI结构 -->
    <input type="file" id="file1">
    <button id="btnUpload">上传文件</button>
    <br>
    <img src="" alt="" id="img" width="800">

    <script>
        // 2.验证用户是否选择了文件
        const button = document.querySelector('#btnUpload')
        button.addEventListener('click', function () {
            // 获取到用户选择的文件列表
            const files = document.querySelector('#file1').files  
            if (files.length <= 0) { // 判断用户是否选择了文件
                alert('请选择要上传的文件!')
            }
            // 3.向FormData中追加文件
            const fd = new FormData()
            fd.append('avatar', files[0])

            // 4.使用xhr发起文件上传的请求
            const xhr = new XMLHttpRequest()            
            xhr.open('POST', 	'http://www.liulongbin.top:3006/api/upload/avatar')
            xhr.send(fd)

            // 5.监听onreadystatechanges事件
            xhr.onreadystatechanges = function () {
                if (xhr.readyState === 4 && xhr.status === 200) {
                    const data = JSON.parse(xhr.responseText)
                    if (data.status === 200) {
                        // 上传成功
                        document.querySelector('#img').src = 'http://www.liulongbin.top:3006' + data.url

                    } else {
                        // 上传失败
                        console.log('文件上传失败!' + data.message)
                    }
                }
            }

        })
    </script>
  • files属性是一个文件数组

监听文件上传的进度:

xhr.upload.onprogress = function (e) {

                if (e.lengthComputable) {   // 
                    // 计算出上传的进度
                    const uploadProgress = Math.ceil((e.loaded / e.total) * 100)
                    console.log(uploadProgress)
                    // 动态设置进度条
                    $("#precent").attr('style', 'width: ' + uploadProgress + '%;').html(uploadProgress + ' % ')
                }
            }
  • xhr.upload.onprogress: 监听文件上传进度的事件
  • e.lengthComputable:是一个布尔值,表示当前上传的资源是否具有可计算的长度
  • e.loaded: 已传输的字节
  • e.total: 需要传输的总字节

监听上传完成事件:

xhr.upload.onload = function () {
                // 移除上传中的类样式 添加上传完成的类样式
                $('#precent').removeClass().addClass('progress-bar progress-bar-success')
            }

            xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar')
            xhr.send(fd)
  • xhr.upload.onload: 监听文件上传完成的事件

5.用jquery实现文件上传

	<!-- 定义UI结构 -->
    <input type="file" id="file1">
    <button id="btnUpload">上传文件</button>
    <br>
    <img src="images/loading.gif" alt="" id="loading" style="display: none;">
    
    <script>
        
        $(function () {
            $(document).ajaxStart(function () {    
                $("#loading").show()
            })
             
            $(document).ajaxStop(function () {      
                $("#loading").hide()
            })

            $("#btnUpload").on('click', function () {
                const files = $("#file1")[0].files
                if (files.length <= 0) {
                    return alert('请选择要上传的文件!')
                }
                // 向FormDate中追加文件
                const fd = new FormData()
                fd.append('avatar', files[0])
                // 使用Jquery发起上传文件的请求
                $.ajax({
                    method: 'POST',
                    url: 'http://www.liulongbin.top:3006/api/upload/avatar',
                    data: fd,
                    // 必写, 不修改Content-Type属性,使用FormData默认的Content-Type值
                    contentType: false,
                    // 必写,不对FormData中的数据进行url编码,使用FormData数据原样发送到服务器
                    processData: false,
                    success: function (res) {
                        console.log(res)
                    }
                })
            })
        })
    </script>
  • ajaxStart(callback): 监听当前文档内所有的ajax请求

  • ajaxStop(callback): 监听当前文档内ajax结束时的请求

6.Axios

axios是专注于网络数据请求的库,相比原生XMLHttpRequst对象,axios简单易用,相比jquery,axios更加轻量化,只专注于网络数据请求。

首先需要引入axios.js文件

<script src="lib/axios.js"></script>

1.axios的基本使用

(1).axios发起get请求

axios.get(url,{params:参数对象}).then(callback)

		    // 请求地址
            const url = 'http://www.liulongbin.top:3006/api/get'
            // 请求的参数对象
            const data = { name: '张三', age: 18 }

            axios.get(url, { params: data }).then(function (res) {
                // console.log(res)
                console.log(res.data) 
            })
  • res.data才是服务器响应回来的真实数据

(2).axios发起post请求

axios.post(url,参数对象).then(callback)

			const url = 'http://www.liulongbin.top:3006/api/post'
			const data = { address: '广西', location: '南宁' }
			axios.post(url, data).then(function (res) {
                console.log(res.data)
            })

2.直接使用axios()发起请求

(1)axios()发起get请求

		axios({
                method: 'GET',
                url: 'http://www.liulongbin.top:3006/api/get',
                params: {
                    name: '张三',
                    age: 19
                },
                then: function (res) {
                    console.log(res.data)
                }
            })
  • 发起get请求需要携带参数时使用的是parms

(2)axios()发起post请求

		axios({
                method: 'POST',
                url: 'http://www.liulongbin.top:3006/api/post',
                data: {
                    address: '广西',
                    location: '南宁'
                },
                then: function (res) {
                    console.log(res.data)
                }
            })
  • 发起post请求需要携带参数时使用的是data
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值