Ajax概念和原理和实际应用

67 阅读10分钟

一、AJAX概念及其工作原理

1.AJAX的概念

AJAX​ 分为二部分,其第一部分为Asynchronous Javascript​,意思为异步的javascript,第二部分为xml,意思为可扩展标记语言,总而言之ajax就是指一种创建交互式网页应用的网页开发技术。

Ajax​是一种异步请求数据的web开发技术,在ajax出现之前,不存在网页局部刷新的做法,用户每次与网页进行交互,就必须进行全部刷新,哪怕是点击一个表单提交之类的,ajax的整体技术流程为用户点击一个需要请求数据的操作之后。ajax通过异步操作(即不干扰dom渲染的操作,浏览器不会出现白屏等操作)去向服务端拿数据,再拿到数据之后,ajax再交给dom模块进行重绘的操作,网页进行相应的呈现,常见运用场景有表单验证是否登入成功、百度搜索下拉框提示和快递单号查询等等。

Ajax的目的是提高用户体验,较少网络数据的传输量。同时,由于AJAX请求获取的是XML数据而不是HTML文档,因此它也节省了网络带宽,让互联网用户的网络冲浪体验变得更加顺畅。

XML 被设计用来传输和存储数据,(这个内容了解一些就好,现在进行数据通信的都是json后缀的格式了,xml是之前使用的格式了,但是由于之前的叫法,所以ajax中还包括了xml)

HTML 被设计用来显示数据。

XML 指可扩展标记语言(eXtensible Markup Language)。

可扩展标记语言(英语:Extensible Markup Language,简称:XML)是一种标记语言,是从标准通用标记语言(SGML)中简化修改出来的。它主要用到的有可扩展标记语言、可扩展样式语言(XSL)、XBRL和XPath等。

  • XML 指可扩展标记语言(EXtensible Markup Language)。
  • XML 是一种很像HTML的标记语言。
  • XML 的设计宗旨是传输数据,而不是显示数据。
  • XML 标签没有被预定义。您需要自行定义标签。
  • XML 被设计为具有自我描述性。
  • XML 是 W3C 的推荐标准。

大家都知道ajax并非一种新的技术,而是几种原有技术的结合体。它由下列技术组合而成。

1.使用CSS和XHTML来表示。

2.使用DOM模型来交互和动态显示。

3.使用XMLHttpRequest来和服务器进行异步通信。

4.使用javascript来绑定和调用。

AJAX 的核心是 XMLHttpRequest 对象。

不同的浏览器创建 XMLHttpRequest 对象的方法是有差异的。

IE 浏览器使用 ActiveXObject,而其他的浏览器使用名为 XMLHttpRequest 的 JavaScript 内建对象

2.AJAX的工作原理

Ajax​的原理简单来说通过XmlHttpRequest​对象来向服务器发异步请求,从服务器获得数据,然后用JavaScript​来操作DOM​而更新页面,我们也可以说XmlHttpRequest​就是在用户和服务器之间加了—个中间层(AJAX引擎),使用户操作与服务器响应异步化,其意思为并不是所有的用户请求都提交给服务器,像—些数据验证和数据处理等都交给Ajax引擎自己来做,,只有确定需要从服务器读取新数据时再由Ajax引擎代为向服务器提交请求,下面是图示:

image-20240309151019-211tfnj.png

再来看看它们各自的交互

image-20240309151153-1q3m621.png

image-20240309151202-93akyl1.png

其ajax的流程图如下

image-20240309151239-7w21qcu.png

下面来一个例子方便我们的理解:

我们去饭店点餐,店家一般都会拿个菜单给我们,然后店家就可以去做其他事情,直到我们点好菜之后,我们才最后跟店家菜单,告诉店家我们需要什么菜品

Ajax​请求数据流程与我们点菜类似,我们的菜单就相当于XMLHttpRequest​对象,顾客就相当于浏览器,店家的服务人员就相当于服务器

浏览器可以发送HTTP​请求后,接着做其他事情,等收到XHR​返回来的数据再进行操作

二、XMLHttpRequest对象的属性、方法、事件

1.XMLHttpRequest对象的属性

  1. readyState​:这个属性表示请求的状态。它包含五个可能的值:

    • 0​ (UNSENT):对象已创建,但尚未初始化(尚未调用open()​方法)。
    • 1​ (OPENED):对象已初始化,但尚未发送请求(尚未调用send()​方法)。
    • 2​ (HEADERS_RECEIVED):请求已发送,且头信息已收到。
    • 3​ (LOADING):下载中;响应体已收到部分数据。
    • 4​ (DONE):下载操作已完成,或操作已失败。
  2. status​:这个属性返回从服务器接收的HTTP状态码(例如,200表示成功,404表示未找到)。这个属性只在请求完成(即readyState​为4)后才可用。

  3. statusText​:这个属性返回HTTP状态文本(如"OK"对应200状态码)。这个属性也只在请求完成后才可用。

  4. responseText​:这个属性以字符串的形式返回从服务器接收到的响应体。这个属性在请求完成且状态码为200或304时可用。

  5. responseXML​:这个属性将响应体解析为Document​对象,如果响应是XML的话。如果响应不是XML,这个属性将是null​。

  6. timeout​:这个属性设置请求超时时间(以毫秒为单位)。如果请求花费的时间超过这个值,请求将自动终止。

  7. onreadystatechange​:这是一个事件处理器,当readyState​属性改变时会触发。通常,你会在这个事件处理器中检查readyState​的值,并在它等于4时处理响应。

下面是不那么常用的属性

  1. responseType:这个属性用于指定服务器响应的数据类型。它可以设置为空字符串(默认值,表示响应为字符串)、"arraybuffer"(表示响应为ArrayBuffer对象)、"blob"(表示响应为Blob对象)、"document"(表示响应为XML文档)、"json"(表示响应为JavaScript对象)、"text"(表示响应为字符串)等。
  2. response:这个属性返回一个XMLHttpRequest​响应的实体体,其类型由responseType​属性决定。如果responseType​未指定或为空字符串,那么返回的是responseText​。如果responseType​被设置为"json",那么这里将返回一个JavaScript对象。
  3. withCredentials:这个属性是一个布尔值,表示跨站访问控制(CORS)请求是否应包含凭据(如cookies、HTTP认证及客户端SSL证明等)。默认为false​。
  4. upload:这是一个XMLHttpRequestUpload​对象,它提供了上传相关的事件和属性。你可以监听这个对象的进度事件来追踪上传进度。
  5. onloadstartonprogressonabortonerroronloadontimeoutonloadend:这些都是事件处理器属性,分别对应请求的不同阶段(如开始加载、进度更新、请求中止、发生错误、请求成功、超时以及加载结束)。你可以设置这些属性来监听和处理这些事件。

2.XMLHttpRequest对象的方法

  1. open(method, url[, async[, user[, password]]])

    • 初始化一个请求,准备发送到指定的URL。
    • method​:HTTP请求方法(如GET、POST等)。
    • url​:请求的URL。
    • async​:可选参数,表示是否异步处理请求,默认为true​。
    • user​ 和 password​:可选参数,用于身份验证。
  2. send([data])

    • 发送已打开的请求。
    • data​:作为请求主体发送的数据。如果请求方法不需要主体(如GET),则此参数可以为null​或省略。
  3. setRequestHeader(header, value)

    • 在发送请求之前,设置请求头。
    • header​:请求头的名称。
    • value​:请求头的值。
  4. getResponseHeader(header)

    • 获取指定响应头的值。
    • header​:响应头的名称。
  5. getAllResponseHeaders()

    • 获取服务器返回的所有响应头。
  6. abort()

    • 取消(中止)当前请求。
  7. onloadonerroronreadystatechange等事件处理器:

    • 这些不是直接调用的方法,而是可以设置的属性回调函数,用于处理请求的不同阶段的事件。例如,onload​在请求成功完成时触发,onerror​在请求发生错误时触发。

3.XMLHttpRequest对象的事件

  1. onreadystatechange:当 XMLHttpRequest​ 对象的 readyState​ 属性发生变化时触发。readyState​ 属性描述了请求的状态(例如,请求是否已经开始,是否已经完成等)。这是 XMLHttpRequest​ 中最常用的事件。
  2. onload:当请求成功完成时触发。此时,你可以通过 XMLHttpRequest​ 对象的 responseText​ 或 responseXML​ 属性获取服务器的响应。
  3. onloadstart:当请求开始发送时触发。此时,请求可能尚未接收到任何响应。
  4. onprogress:在请求过程中,如果可用,会定期触发此事件,以报告下载进度。可以通过 XMLHttpRequest​ 对象的 loaded​ 和 total​ 属性获取已接收和预期接收的字节数。
  5. onerror:当请求发生错误时触发。这可能是由于网络问题、跨域请求限制、服务器错误等原因造成的。
  6. onabort:当请求被用户或脚本取消时触发。例如,你可以通过调用 XMLHttpRequest​ 对象的 abort()​ 方法来取消请求。
  7. ontimeout:当请求由于超时而失败时触发。可以通过 XMLHttpRequest​ 对象的 timeout​ 属性设置超时时间(以毫秒为单位)。
  8. onloadend:无论请求成功还是失败,当请求完成时都会触发此事件。这可以用于清理在请求期间创建的资源。

三、Ajax及XMLHttpRequest对象的用法和应用场景

下面我将使用免费的JSONPlaceHolder为http接口来进行请求,使用不同的应用场景来进行操作

JSONPlaceholder 附带一组 6 种通用资源:

image-20240309154139-z3vsdfp.png

以下是其所以接口配置

1、帖子接口:

获取帖子列表:jsonplaceholder.typicode.com/posts
根据帖子ID获取详情:jsonplaceholder.typicode.com/posts/1
获取某个用户所有的帖子:jsonplaceholder.typicode.com/posts?userI…
2、评论接口

获取评论列表:jsonplaceholder.typicode.com/comments
获取某个帖子的所有评论(两种方式):jsonplaceholder.typicode.com/comments?po…
获取某个帖子所有的评论(两种方式):jsonplaceholder.typicode.com/posts/1/com…
3、专辑接口:

获取专辑列表:jsonplaceholder.typicode.com/albums
根据专辑ID获取详情:jsonplaceholder.typicode.com/albums/6
获取某个用户所有专辑:jsonplaceholder.typicode.com/albums?user…
4、待办事宜接口:

获取待办事宜列表:jsonplaceholder.typicode.com/todos
根据待办ID获取详情:jsonplaceholder.typicode.com/todos/6
获取某个用户所有待办事宜:jsonplaceholder.typicode.com/todos?userI…
5、用户接口:

获取用户列表:jsonplaceholder.typicode.com/users
根据用户ID获取详情:jsonplaceholder.typicode.com/users/5
6、照片接口:

获取照片列表:jsonplaceholder.typicode.com/photos
根据照片ID获取详情:jsonplaceholder.typicode.com/photos/8
获取某个专辑所有照片:jsonplaceholder.typicode.com/photos?albu…

1.获取用户名字列表

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>User List</title>
</head>

<body>
    <h1>User List</h1>
    <ul id="userList"></ul>

    <script>
        document.addEventListener("DOMContentLoaded", function () {
            var userList = document.getElementById("userList");
            var xhr = new XMLHttpRequest();
            //进行get请求,请求客户数据
            xhr.open("GET", "https://jsonplaceholder.typicode.com/users");
            //加载完成之后,我们进行渲染操作
            xhr.onload = function () {
                //进行判断保证其请求OK的适合拿数据
                if (this.status == 200) {
                    let users = JSON.parse(xhr.responseText);
                    users.forEach(item => {
                        let peopleName = document.createElement('li')
                        peopleName.textContent = item.name;
                        userList.appendChild(peopleName)
                    });
                } else {
                    console.log('请求失败');
                }
            }
            xhr.send();

        });
    </script>
</body>

</html>

image-20240309162634-1ew8p9o.png

2.添加用户

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>User List</title>
</head>

<body>
    <h1>User List</h1>
    <ul id="userList"></ul>

    <h2>Add New User</h2>
    <form id="newUserForm">
        <label for="name">Name:</label>
        <input type="text" id="name" name="name" required>

        <label for="email">Email:</label>
        <input type="email" id="email" name="email" required>

        <input type="submit" value="Add User">
    </form>

    <script>
        document.addEventListener("DOMContentLoaded", function () {
            var userList = document.getElementById('userList');
            var newUserForm = document.getElementById('newUserForm');

            // 监听表单提交事件  
            newUserForm.addEventListener('submit', function (event) {
                //不让其默认提交,不然就按本地链接走了
                event.preventDefault();
                //创建一个新的XML
                let xhr = new XMLHttpRequest();
                //获取到值,方便我们后面封装
                let nameshuru = document.getElementById('name').value;
                let emailshuru = document.getElementById('email').value;

                let userdata = {
                    name: name,
                    username: name, // JSONPlaceholder要求username和name相同  
                    email: email
                }
                //先open,在监听,在send
                xhr.open('POST', 'https://jsonplaceholder.typicode.com/users', true);
                //外面发送json格式,必须设置MIME为JSON
                xhr.setRequestHeader('Content-Type', 'application/json');
                xhr.onreadystatechange = function () {
                    if (xhr.status == '201') {//表示提交成功
                        alert('添加用户成功');
                    } else {
                        alert('添加用户失败');
                    }
                }
                xhr.send(JSON.stringify(userdata))//将对象转成字符串发送给服务端,必须要的操作
            });
        });
    </script>
</body>

</html>

image-20240309162610-3lu3ebh.png