AJAX —— 原生 AJAX / jQuery 发送 AJAX / axios 发送 AJAX / fetch 发送 AJAX

一、原生 AJAX


1. AJAX 简介

AJAX,即 Asynchronous JavaScript and XML 的缩写,指的是通过 JavaScript 的异步通信,从服务器获取 XML 文档从中提取数据,再更新当前网页的对应部分,而 不用刷新整个网页

后来,AJAX 这个词就成为 JavaScript 脚本发起 HTTP 通信的代名词,也就是说,只要用脚本发起通信,就可以叫做 AJAX 通信。

AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。

具体来说,AJAX 包括以下几个步骤:

在这里插入图片描述

概况来说,AJAX 通过原生的 XMLHttpRequest 对象发出 HTTP 请求,得到服务器返回的数据后,再进行处理

 

2. XML 简介


XML 可扩展标记语言,是一种用于标记电子文件使其具有结构性的标记语言。XML 被用于存储和传输数据。

XML 和 HTML 类似,不同的是 HTML 中都是预定义标签,而 XML 中没有预定义标签,全都是自定义标签,用来表示一些数据。

例如,对于一个学生数据 name = "孙悟空" ; age = 18; gender = "男" 可以用 XML 表示为

<student>
	<name>孙悟空</name>
	<age>18</age>
	<gender></gender>
</student>

现在,服务器返回的都是 JSON 格式的数据,XML 格式已经被 JSON 取代了。JSON 表示为

{"name":"孙悟空", "age":18, "gender":"男"}

 

3. AJAX 特点


  • 优点
  1. 可以在页面不刷新的情况下,向服务端发送请求
  2. 允许根据用户事件(如鼠标事件、键盘事件、表单事件等)来更新部分页面内容
  • 缺点
  1. 没有浏览历史,不能回退
  2. 存在跨域问题(同源)。如 a.com 网页打算向 b.com 网页发送请求,Ajax 默认是不允许的。
  3. SEO 搜索引擎优化不友好,爬虫爬取不到网页中相关数据

 

4. XMLHttpRequest 对象


AJAX 的核心是 XMLHttpRequest 对象。它用于同幕后服务器交换数据,这意味着可以更新网页的部分,而不需要重新加载整个页面。

  • 创建语法
const xhr = new XMLHttpRequest();
  • 对象方法

先简单进行列举,后文用到时详解。
在这里插入图片描述

  • 对象属性

先简单进行列举,后文用到时详解。
在这里插入图片描述
 

5. 向服务器发送请求


如需向服务器发送请求,我们使用 XMLHttpRequest 对象的 open()send() 方法。如下:

  1. GET 请求
	xhr.open('GET', 'http://127.0.0.1:8000/server');
	// 3. 发送
	xhr.send();
  1. POST 请求
	xhr.open('POST', 'http://127.0.0.1:8000/server');
	xhr.send();

如需像 HTML 表单那样 POST 数据,需要通过 setRequestHeader() 添加一个 HTTP 头部。

	xhr.open('POST', 'http://127.0.0.1:8000/server');
	xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	xhr.send('a=100&b=200&c=300');
  • open 方法

初始化 HTTP 请求参数,但不会发送请求。

	xhr.open(method, url [, async][,user][,pwd])
  1. method:要使用的 HTTP 方法,比如 GETPOST 等。
  2. url:要向其发送请求的 URL 。
  3. async:可选,表示是否异步执行操作,默认为 truetrue 表示通过异步发送请求;false 表示同步发送请求,将停止执行直到服务器响应就绪(不推荐使用)。
  4. user:可选,用户名称。
  5. pwd:可选,密码。
  • send 方法

这个方法导致一个 HTTP 请求发送。

	xhr.send(body)		

GET 请求不传 body 参数,只有 POST 请求使用。

如果之前没有调用 open(),或者更具体地说,如果 readyState 不是 1,send() 抛出一个异常。否则,它发送一个 HTTP 请求,该请求由以下几部分组成:

  1. 之前调用 open() 时指定的 HTTP 方法、URL 以及认证资格(如果有的话)。
  2. 之前调用 setRequestHeader() 时指定的请求头部(如果有的话)。
  3. 传递给这个方法的 body 参数。
  • setRequestHeader 方法

向请求添加 HTTP 头部,也就是设置请求头信息。此方法必须在 open() 方法和 send() 之间调用。

	setRequestHeader(header, value)		
  1. header:规定头部名称
  2. value:规定头部值

一般我们设置的是:content-type,传输数据类型,即服务器需要我们传送的数据类型

	xhr.setRequestHeader ("content-type", "application/x-www-form-urlencoded" )

 

6. 接收服务器响应


  • readyState

readyState 保存了 XMLHttpRequest 的状态。其属性值对应描述如下:

属性值 描述
0 XMLHttpRequest 对象已创建或已被 abort() 方法重置
1 open() 方法已调用, send() 方法未调用。请求还没有被发送
2 send() 方法已调用,HTTP 请求已发送到 Web 服务器,但还未接收到响应
3 所有响应头部都已经接收到,响应体开始接收但未完成
4 请求已完成且 HTTP 响应已经完全接收

每当 readyState 发生变化时就会调用 onreadystatechange 函数。

  • status

请求的状态码,HTTP 响应中状态行的一部分。不同的状态码代表不同的含义,如下:

状态码 描述
1xx 表示 HTTP 请求已经接受,继续处理请求
2xx 表示 HTTP 请求已经处理完成
3xx 表示把请求访问的 URL 重定向到其他目录
4xx 表示客户端出现错误
5xx 表示服务器端出现错误

常用的状态码:

状态码 描述
200 表明该请求被成功地完成,所请求的资源发送回客户端
403 Forbidden 禁止访问
404 Not Found 资源不存在
  • onreadystatechange

onreadystatechange 属性定义当 readyState 发生变化时执行的函数。

看下面示例。

xhr.onreadystatechange = () => {
    // 判断
    if (xhr.readyState === 4) {
        if (xhr.status >= 200 && xhr.status < 300) {
            // 处理结果
            document.querySelector('div').innerHTML = xhr.response;
        }
    }
}

如上代码表示:当可以成功访问且有响应时,将响应信息写入到 div 中。

  • responseType

XMLHttpRequest 属性 responseType 是一个枚举字符串值,用于指定响应中包含的数据类型。它还允许作者更改响应类型。如果将 responseType 的值设置为空字符串,则会使用 text 作为默认值。

描述
"" 与默认类型 “text” 相同
"arraybuffer" response 是一个包含二进制数据的 JavaScript ArrayBuffer
"blob" response 是一个包含二进制数据的 Blob 对象
"document" response 是一个 HTML Document 或 XML XMLDocument,根据接收到的数据的 MIME 类型而定。
"text" response 是 DOMString 对象中的文本
"json" response 是通过将接收到的数据内容解析为 JSON 而创建的 JavaScript 对象

如下示例,设置响应体数据类型为 json

xhr.responseType = 'json';

xhr.onreadystatechange = () => {
	if (xhr.readyState === 4) {
        if (xhr.status >= 200 && xhr.status < 300) {
            // {name: "zhangsan"}
            result.innerHTML = xhr.response.name;	// zhangsan
        }
    }
}

当然,你也可以手动对数据进行转换,只不过显得有些麻烦。如下

	// {name: "zhangsan"}
	let data = JSON.parse(xhr.response);
	result.innerHTML = data.name;		// zhangsan

 

7. AJAX 的使用


下图表示 AJAX 工作流程:
在这里插入图片描述

下面两个示例,分别为向服务器发送 GET 和 POST 请求。

  • 向服务器发送 GET 请求

需求:点击按钮,向服务端发送 GET 请求;响应结果在 div 呈现
请添加图片描述

前端页面 index.html

<button>点击发送请求</button>
<div id="result"></div>

<script>
    // 绑定事件
    const btn = document.querySelector('button');
    const result = document.querySelector('#result');

    btn.addEventListener('click', () => {
        // 1. 创建对象
        const xhr = new XMLHttpRequest();
        // 2. 初始化:设置请求方法 和 url
        xhr.open('GET', 'http://127.0.0.1:8000/server');
        // 3. 发送
        xhr.send();
        // 4. 事件绑定:处理服务端返回结果
        xhr.onreadystatechange = () => {
            // readystate 是 xhr 对象的属性: 表示状态 0 1 2 3 4    
            if (xhr.readyState === 4) {
                // 判断响应状态码 200 401 403 404 500 
                // 2xx 表示 成功
                if (xhr.status >= 200 && xhr.status < 300) {
                    // 处理结果:行 头 空行 体
                    result.innerHTML = xhr.response;
                } else {

                }
            }
        }
    })
</script>

服务器端 sever.js

const express = require('express');

// 创建应用对象
const app = express();

// 创建路由规则
app.get('/sever', (req, res) => {
    // 设置响应头:设置允许跨域
    res.setHeader('Access-Control-Allow-Origin', '*');
    // 设置响应
    res.send('Hello AJAX');
})

// 监听端口启动服务
app.listen(8000, () => {
    console.log('服务已经启动, 8000 端口监听中...');
})
  • 向服务器发送 POST 请求

请添加图片描述

前端页面 index.html

<div id="result"></div>
<script>
    const result = document.querySelector('#result');

    result.addEventListener('mouseenter', function () {
        // 1. 创建对象
        const xhr = new XMLHttpRequest();
        // 2. 初始化
        xhr.open('POST', 'http://127.0.0.1:8000/server');
        // 3. 发送
        xhr.send();
        xhr.onreadystatechange = () => {
            // 判断
            if (xhr.readyState === 4) {
                if (xhr.status >= 200 && xhr.status < 300) {
                    // 处理结果
                    result.innerHTML = xhr.response;
                }
            }
        }
    })
</script>

服务器端 sever.js

const express = require('express');

// 创建应用对象
const app = express();

// 创建路由规则
app.post('/sever', (req, res) => {
    // 设置响应头:设置允许跨域
    res.setHeader('Access-Control-Allow-Origin', '*');
    // 设置响应
    res.send('Hello AJAX POST');
})

// 监听端口启动服务
app.listen(8000, () => {
    console.log('服务已经启动, 8000 端口监听中...');
})

 

8. 请求超时与网络异常处理


  • 请求超时

我们可以使用一个超时设置来设置一个时间,到时自动取消请求。进而避免代码为了等候读取请求的返回数据长时间执行。

超时毫秒数可以通过为 XMLHttpRequest 对象的 timeout 属性赋值来指定:

    xhr.timeout = 2000;			// 指定超时时间 2s

同时还可以为 timeout 事件的 ontimeout 事件句柄指定事件处理函数,如下:

    xhr.ontimeout = () => {
        alert('请求超时,稍后重试');		// 超时后触发
    }
  • 网络异常

XMLHttpRequestEventTarget.onerror 是 XMLHttpRequest 事务由于错误而失败时调用的函数。

请注意只有在网络层级出现错误时才会调用此函数。如果错误只出现在应用层(比如发送一个HTTP的错误码),这个方法将不会被调用。

    // 网络异常
    xhr.onerror = () => {
        alert('你的网络似乎除了一些问题');		// 网络异常时触发
    }

注意:可以通过下面操作设置断网
在这里插入图片描述

 

9. AJAX 取消请求


XMLHttpRequest.abort() 方法:如果该请求已被发出,利用此方法将终止该请求。

如下所示:
请添加图片描述

    const btns = document.querySelectorAll('button');
    let xhr = null;

    btns[0].addEventListener('click', () => {
        xhr = new XMLHttpRequest();
        xhr.open('GET', 'http://127.0.0.1:8000/delay');
        xhr.send();
        // 不需要返回什么结果,可以不加事件绑定
    })

    // abort
    btns[1].addEventListener('click', () => {
        xhr.abort();
    })
  • 应用:解决请求重复发送问题

如果同意请求被重复发送,会使得服务器压力比较大,效率变低的问题。

解决方法:创建标识变量,通过标识变量判断此前的请求是否已经完成,未完成则利用 abort() 取消此次请求。

    const btn = document.querySelector('button');
    let xhr = null;

    // 标识变量:是否正在发送 AJAX 请求
    let isSending = false;

    btn.addEventListener('click', () => {
        // 首先判断标识变量
        if (isSending) x.abort();
        xhr = new XMLHttpRequest();
        isSending = true;
        xhr.open('GET', 'http://127.0.0.1:8000/delay');
        xhr.send();
        xhr.onreadystatechange = () => {
            if (xhr.readyState === 4) {
                isSending = false;
            }
        }
    })

 

二、jQuery 中 AJAX 请求


详细内容可查阅文档 :jQuery API - AJAX

1. $.ajax()

通过 HTTP 请求加载远程数据。这是 jQuery 底层 AJAX 实现。简单易用的高层实现见 $.get$.post 等。

$.ajax() 返回其创建的 XMLHttpRequest 对象。

$.ajax(url,[settings])
  1. url:一个用来包含发送请求的 URL 字符串。
  2. settings:AJAX 请求设置。所有选项都是可选的。
  • settings 选项

可选的选项有很多,这里简单列举一些常用的作为说明。

  1. data:发送到服务器的数据。将自动转换为请求字符串格式。
  2. dataType:指定服务器返回的数据类型。如,xmlhtmljsonscripttext
  3. type:请求方式。默认 GET 请求,也可以设置为 POST。注意:其他 HTTP 请求方法,如 PUT 和 DELETE 也可以使用,但仅部分浏览器支持。
  4. timeout:设置请求超时时间。
  5. headers:设置头信息。
  6. async:(默认: true) 默认设置下,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为 false。

除此外,还有几种回调函数可作为参数选项

  1. beforeSend(XHR):发送请求前可修改 XMLHttpRequest 对象的函数,如添加自定义 HTTP 头。XMLHttpRequest 对象是唯一的参数。
  2. success(data, textStatus, jqXHR):请求成功后的回调函数。参数:由服务器返回,并根据 dataType 参数进行处理后的数据;描述状态的字符串。还有 jqXHR(在jQuery 1.4.x的中,XMLHttpRequest) 对象 。在jQuery 1.5, 成功设置可以接受一个函数数组。每个函数将被依次调用。
  3. error:请求失败时调用此函数。有以下三个参数:XMLHttpRequest 对象、错误信息、(可选)捕获的异常对象。如果发生了错误,错误信息(第二个参数)除了得到null之外,还可能是 "timeout""error""notmodified""parsererror"
  4. complete(XHR, TS):请求完成后回调函数 (请求成功或失败之后均调用)。参数: XMLHttpRequest 对象和一个描述成功请求类型的字符串。
  • 示例
    $('button').eq(2).click(() => {
        $.ajax({
            // url
            url: 'http://127.0.0.1:8000/jquery-server',
            // 参数
            data: { a: 100, b: 200 },
            // 请求类型
            type: 'GET',
            // 响应体结果
            dataType: 'json',
            // 成功的回调
            success: (data) => {
                console.log(data);
            },
            // 超时时间
            timeout: 2000,
            // 失败的回调
            error: () => {
                console.log('出错啦.....');
            },
            // 头信息
            headers: {
                c: 300,
                d: 400
            }
        });
    })

 

2. $.get


通过远程 HTTP GET 请求载入信息。请求成功时可调用回调函数。如果需要在出错时执行函数,请使用 $.ajax

	$.get(url, [data], [callback], [type])
  1. url:请求的 URL 地址。
  2. data:请求携带的参数。
  3. callback:载入成功时回调函数。可以接收响应体参数(data)。
  4. type:设置响应体类型。如,xml, html, script, json, text, _default
  • 示例一

请求 test.php 网页,忽略返回值。

	$.get("test.php");
  • 示例二

请求 test.php 网页,传送 2 个参数,忽略返回值。

	$.get("test.php", { name: "John", time: "2pm" } );
  • 示例三

请求 http://127.0.0.1:8000/jquery-server 网页,传送 2 个参数,添加回调,成功时打印以 json 格式打印回调信息。

    $('button').eq(0).click(() => {
        $.get('http://127.0.0.1:8000/jquery-server', {
            a: 100,
            b: 200
        }, (data) => {
            console.log(data);
        }, 'json');
    })

 

3. $.post


和 GET 请求相似。通过远程 HTTP POST 请求载入信息。

	$.post(url, [data], [callback], [type])
  1. url:请求的 URL 地址。
  2. data:请求携带的参数。
  3. callback:载入成功时回调函数。
  4. type:设置返回内容格式,xml, html, script, json, text, _default
    $('button').eq(1).click(() => {
        $.post('http://127.0.0.1:8000/jquery-server', {
            a: 100,
            b: 200
        }, (data) => {
            console.log(data);
        });
    })

 

三、axios 发送 AJAX 请求


官方文档:axios 中文文档

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。简单的讲就是可以发送 GET、POST 请求。
 

1. axios 特性


  • 从浏览器中创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF
     

2. axios 安装


  • 使用 npm
$ npm install axios
  • 使用 bower
$ bower install axios
  • 使用 cdn
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

 

3. axios 使用


  • GET 请求
// 配置 baseURL
axios.defaults.baseURL = 'http://127.0.0.1:8000';

btns[0].onclick = function () {
    axios.get('/axios-server', {
        // url 参数
        params: {
            id: 100,
            vip: 7
        },
        // 请求头信息
        headers: {
            name: 'zs',
            age: 18
        }
    }).then(value => {
        console.log(value);
    });
}

在这里插入图片描述
想要处理返回结果,后面跟 then() 方法处理即可。

  • POST 请求
axios.post(url[, data[, config]])

示例

    axios.post('/axios-server', {
        // 请求体
        username: 'admin',
        password: 'admin'
    }, {
        // url
        params: {
            id: 200,
            vip: 9
        },
        // 请求头参数
        headers: {
            height: 180,
            weight: 170
        }
    })

在这里插入图片描述

  • 通用方式

可以通过向 axios 传递相关配置来创建请求。

axios(config)

示例如下

    axios({
        // 请求方法
        method: 'POST',
        // url
        url: '/axios-server',
        // url 参数
        params: {
            vip: 10,
            level: 30
        },
        // 头信息
        headers: {
            a: 100,
            b: 200
        },
        // 请求体参数
        data: {
            username: 'admin',
            password: 'admin'
        }
    }).then(response => {
        // 响应状态码
        console.log(response.status);
        // 响应状态字符串
        console.log(response.statusText);
        // 响应头信息
        console.log(response.headers);
        // 响应体
        console.log(response.data);
    })

在这里插入图片描述
 

四、fetch 发送 AJAX 请求


fetch() 方法用于发起获取资源的请求。它返回一个 Promise,这个 Promise 会在请求响应后被 resolve,并传回 Response 对象。

fetch() 方法的参数与 Request() 构造器是一样的。

   fetch('http://127.0.0.1:8000/fetch-server', {
       // 请求方法
       method: 'POST',
       // 请求头
       headers: {
           name: 'zs'
       },
       // 请求体
       body: 'username=admin&password=admin'
   }).then(response => {
       return response.text();
   }).then(response => {
       console.log(response);  
   });

参考:

1) W3school - AJAX 教程

2)【尚硅谷】3小时 Ajax 入门到精通

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>