深度剖析Ajax 的工作原理

1. AJAX的工作原理

Ajax的工作原理相当于在用户和服务器之间加了—个中间层(AJAX引擎),使用户操作与服务器响应异步。但并不是所有的用户请求都提交给服务器,像—些数据验证和数据处理等都交给Ajax引擎自己来做, 只有确定需要从服务器读取新数据时再由Ajax引擎代为向服务器提交请求。如图:

在这里插入图片描述
同时要想弄明白ajax原理必须了解XMLHTTPRequest对象
我们知道Ajax的一个最大的一个特点就是是无刷新更新页面,这一特点主要得益于XMLHTTP组件XMLHTTPRequest对象。

2. XMLHTTPRequest对象。

  • XMLHttpRequest(简称 xhr)是浏览器提供的 Javascript 对象,通过它,可以请求服务器上的数据资源
  • XMLHttpRequest对象用于与服务器交互。通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定URL,获取数据。这允许网页在不影响用户操作的情况下,更新页面的局部内容

XMLHTTPRequest对象使用步骤:

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

注意xhr对象的readyState属性
XMLHttpRequest 对象的 readyState 属性,用来表示当前 Ajax 请求所处的状态。每个 Ajax 请求必然处于以下状态中的一个

状态描述
0UNSENTXMLHttpRequest 对象已被创建,但尚未调用 open方法。
1OPENEDopen() 方法已经被调用。
2HEADERS_RECEIVEDsend() 方法已经被调用,响应头也已经被接收。
3LOADING数据接收中,此时 response 属性中已经包含部分数据。
4DONEAjax 请求完成,这意味着数据传输已经彻底完成或失败

HTTP响应状态码的组成及分类:

HTTP 状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字用来对状态码进行细分。
HTTP 状态码共分为 5 种类型:

分类分类描述
1**信息,服务器收到请求,需要请求者继续执行操作(实际开发中很少遇到 1** 类型的状态码)
2**成功,操作被成功接收并处理
3**重定向,需要进一步的操作以完成请求
4**客户端错误,请求包含语法错误或无法完成请求
5**服务器错误,服务器在处理请求的过程中发生了错误

具体状态码参考:菜鸟教程

2.1 使用xhr发GET请求

使用xhr发起带参数的GET请求

定义:查询字符串(URL 参数)是指在 URL 的末尾加上用于向服务器发送信息的字符串(变量)。

格式:将英文的 ? 放在URL 的末尾,然后再加上 参数=值 ,想加上多个参数的话,使用 & 符号进行分隔。以这个形式,可以将想要发送给服务器的数据添加到 URL 中。

使用 xhr 对象发起带参数的 GET 请求时,只需在调用 xhr.open 期间,为 URL 地址指定参数即可:

xhr.open(‘GET’, 'http://www.liulongbin.top:3006/api/getbooks?id=1')
这种在 URL 地址后面拼接的参数,叫做查询字符串

GET请求带参数的本质

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

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

$.ajax({ method: 'GET', url: 'url', data: {name: 'zs', age: 20}, success: function() {} })
// 等价于
$.ajax({ method: 'GET', url: 'url?name=zs&age=20', success: function() {} })

如何对URL进行编码与解码

浏览器提供了 URL 编码与解码的 API,分别是:

  • encodeURI() 编码的函数
  • decodeURI() 解码的函数

2.2 使用xhr发起POST请求

XML对象发起post请求使用步骤:

  1. 创建 xhr 对象
  2. 调用 xhr.open() 函数
  3. 设置 Content-Type 属性(固定写法)
  4. 调用 xhr.send() 函数,同时指定要发送的数据
  5. 监听 xhr.onreadystatechange 事件
// 1. 创建 xhr 对象
var xhr = new XMLHttpRequest()
// 2. 调用 open()
xhr.open('POST', 'http://www.liulongbin.top:3006/api/addbook')
// 3. 设置 Content-Type 属性(固定写法)
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
// 4. 调用 send(),同时将数据以查询字符串的形式,提交给服务器
xhr.send('bookname=水浒传&author=施耐庵&publisher=天津图书出版社')
// 5. 监听 onreadystatechange 事件
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4 && xhr.status === 200) {
        console.log(xhr.responseText)
    }
}

3. xhr对象上传图像文件文件

新版 XMLHttpRequest 对象,不仅可以发送文本信息,还可以上传文件。

实现步骤:

  1. 定义 UI 结构
  2. 验证是否选择了文件
  3. 向 FormData 中追加文件
  4. 使用 xhr 发起上传文件的请求
  5. 监听 onreadystatechange 事件
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>

    <!-- CDN引入 -->
    <link href="http://libs.baidu.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet" />
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.slim.min.js"></script>
</head>

<body>
    <!-- 1. 文件选择框 -->
    <input type="file" id="file1" />
    <!-- 2. 上传文件的按钮 -->
    <button id="btnUpload">上传文件</button>

    <!-- bootstrap 中的进度条 -->
    <div class="progress" style="width: 500px; margin: 15px 10px;">
        <div class="progress-bar progress-bar-striped active" style="width: 0%" id="percent">
            0%
        </div>
    </div>

    <br />
    <!-- 3. img 标签,来显示上传成功以后的图片 -->
    <img src="" alt="" id="img" width="800" />

    <script>
        // 1. 获取到文件上传按钮
        var btnUpload = document.querySelector('#btnUpload')
            // 2. 为按钮绑定单击事件处理函数
        btnUpload.addEventListener('click', function() {
            // 3. 获取到用户选择的文件列表
            var files = document.querySelector('#file1').files
            if (files.length <= 0) {
                return alert('请选择要上传的文件!')
            }
            var fd = new FormData()
                // 将用户选择的文件,添加到 FormData 中
            fd.append('avatar', files[0])

            var xhr = new XMLHttpRequest()

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

                    }
                }
                // 文件上传成功后重新设置进度条
            xhr.upload.onload = function() {
                $('#percent').removeClass().addClass('progress-bar progress-bar-success')
            }

            xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar')
            xhr.send(fd)

            xhr.onreadystatechange = function() {
                if (xhr.readyState === 4 && xhr.status === 200) {
                    var 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>
</body>

</html>

4. AJAX的优缺点

优点

  1. 局部刷新页面,减少用户等待时间,带来更好的用户体验
  2. 按需取数据,减轻服务器的负担,最大程度减少冗余请求
  3. 异步方式与服务器通信,不需要打断用户的操作,具有更加迅速地响应能力

缺点

  1. Ajax只是局部刷新,所以页面的后退按钮是没用的
  2. 对流媒体还有移动设备的支持不是太好
  3. 客户端过肥,太多客户端代码造成开发商的成本,编写复杂、容易出错,冗余代码比较多,破坏了web的原有标准

详细Ajax 的工作原理参考简书

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于Spring MVC和AJAX文件上传下载,你可以按照以下步骤操作: 文件上传: 1. 创建一个包含文件上传表单的HTML页面。 2. 创建一个Spring MVC控制器,用于处理文件上传的请求。 3. 在控制器中,使用`@RequestMapping`注解来映射文件上传的URL,并使用`@RequestParam`注解来接收文件。 4. 在处理方法中,使用MultipartFile参数来接收上传的文件,并使用`transferTo()`方法将文件保存到指定位置。 文件下载: 1. 创建一个Spring MVC控制器,用于处理文件下载的请求。 2. 在控制器中,使用`@RequestMapping`注解来映射文件下载的URL。 3. 在处理方法中,使用`@PathVariable`注解来接收文件名参数。 4. 使用`ServletContext`对象获取文件路径,并创建一个`File`对象。 5. 使用`ResponseEntity`类设置下载响应的头部信息和内容。 通过AJAX实现文件上传和下载: 1. 使用JavaScript创建一个AJAX请求对象。 2. 使用FormData对象将文件添加到请求中。 3. 发送AJAX请求到Spring MVC控制器的URL,并设置请求方法为POST。 4. 在Spring MVC控制器中,使用MultipartFile参数接收文件,并处理文件上传的逻辑。 5. 在返回的响应中,可以包含上传成功或失败的消息。 注意:在Spring配置文件中,需要配置multipart解析器来支持文件上传。 以上是实现Spring MVC和AJAX文件上传下载的一般步骤,你可以根据具体需求进行适当的调整和扩展。希望对你有所帮助!如果还有其他问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值