第 2 章:AJAX 的使用

2024-09-06 04:52
文章标签 使用 ajax

本文主要是介绍第 2 章:AJAX 的使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

AJAX 的使用

核心对象:XMLHttpRequest,AJAX 的所有操作都是通过该对象进行的。

1. 使用步骤

  1. 创建 XMLHttpRequest 对象
    var xhr = new XMLHttpRequest();

  2. 设置请求信息

xhr.open(method, url);//可以设置请求头,一般不设置
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  1. 发送请求
    xhr.send(body) //get 请求不传 body 参数,只有 post 请求使用

  2. 接收响应

//xhr.responseXML 接收 xml 格式的响应数据
//xhr.responseText 接收文本格式的响应数据
xhr.onreadystatechange = function (){if(xhr.readyState == 4 && xhr.status == 200){var text = xhr.responseText;console.log(text);}
}

2. AJAX 请求状态

  • xhr.readyState 可以用来查看请求当前的状态
  • readyState

readystate是xhr对象中的属性,表示状态0, 1, 2, 3, 4:

  • 0: 表示 XMLHttpRequest 实例已经生成,但是 open()方法还没有被调用。
  • 1: 表示 send()方法还没有被调用,仍然可以使用 setRequestHeader(),设定 HTTP请求的头信息。
  • 2: 表示 send()方法已经执行,并且头信息和状态码已经收到。
  • 3: 表示正在接收服务器传来的 body 部分的数据。
  • 4: 表示服务器数据已经完全接收,或者本次接收已经失败了

3. AJAX发送GET请求

需求:点击按钮,向服务端发送请求,把从服务端返回的响应体结果在文本框里面展示出来(在div里面做一个呈现)

3.1 GET.html

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>AJAX GET 请求</title><style>#result {width: 200px;height: 100px;border: solid 1px #90b;}</style>
</head>
<body><button id="result1">点击发送请求</button><div id="result"></div><script>// 获取button元素const btn = document.getElementById('result1');const result = document.getElementById('result');// 绑定事件btn.onclick = function () {// 1. 创建 XMLHttpRequest 对象const xhr = new XMLHttpRequest();// 2. 初始化 设置请求方法和 urlxhr.open('GET', 'http://127.0.0.1:8000/server');// 发送请求xhr.send();// 4. 事件绑定 处理服务端返回的结果xhr.onreadystatechange = function () {// 判断(服务端返回了所有的结果)if(xhr.readyState === 4) {// 判断响应状态码 200 404 403 401 500// 2xx 成功if (xhr.status >= 200 && xhr.status < 300) {// // 处理结果 行 头 空行 体// // 1. 响应行// console.log(xhr.status); // 状态码// console.log(xhr.statusText); // 状态字符串// console.log(xhr.getAllResponseHeaders()); // 所有响应头// console.log(xhr.response); // 响应体// 设置 result 的文本result.innerHTML = xhr.response;}}}}</script>
</body>
</html>

3.2 server.js

// 1. 引入express
const express = require('express');// 2. 创建应用对象
const app = express();// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
app.get('/server', (request, response) => {// 设置响应头  设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');// 设置响应体response.send('Hello AJAX');
});// 4. 监听端口启动服务
app.listen(8000, () => {console.log('服务已经启动, 8000 端口监听中....');
});

3.3 AJAX设置GET请求参数

  • 直接在url后面用?分割,然后加参数的名与值
  • 如果有多个参数就用&分开
    在这里插入图片描述

4. AJAX发送POST请求

需求:鼠标光标移进文本框,就会向服务端发送请求,服务端返回结果,然后把结果在该框中做一个呈现

4.1 POST.html

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>AJAX POST 请求</title><style>#result {width: 200px;height: 100px;border: solid 1px #903;}</style>
</head>
<body><div id="result"></div><script>// 获取元素对象const result = document.getElementById('result');// 绑定事件result.addEventListener("mouseover", function () {// 1. 创建对象const xhr = new XMLHttpRequest();// 2. 初始化 设置类型 与URLxhr.open('POST', 'http://127.0.0.1:8000/server');// 3. 发送xhr.send(a=100);// 4. 事件绑定xhr.onreadystatechange = function () {// 判断if (xhr.readyState === 4) {// 判断状态码if (xhr.status >= 200 && xhr.status < 300) {// 处理服务端返回的结果result.innerHTML = xhr.response;}}}})</script>
</body>
</html>

4.2 server.js

// 1. 引入express
const express = require('express');// 2. 创建应用对象
const app = express();// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装app.post('/server', (request, response) => {// 设置响应头  设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');// 设置响应体response.send('Hello AJAX POST');
});// 4. 监听端口启动服务
app.listen(8000, () => {console.log('服务已经启动, 8000 端口监听中....');
});

4.3 post设置参数

  • 直接在send里面设置参数
  • 可以自己设置格式,只要服务端能够处理
    在这里插入图片描述
    在这里插入图片描述

5. 设置请求头信息

  • 设置预设头信息
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  • 设置自定义头信息
xhr.setRequestHeader('name', '123');// node.js设置
//请求类型改为all
app.all// 设置可接收自定义请求
response.setHeader('Access-Control-Allow-Headers', '*');

6. 服务端响应JSON数据

需求:按下键盘上的任意按键,就会向服务端发送请求,服务端返回结果,然后把结果在div中做一个呈现

6.1 处理json数据

  1. 因为响应体只能发送字符串,我们可以先在服务端把要响应的数据对其进行字符串转换之后再将其发送

  2. 在客户端处理数据有两种方法,一是手动处理,二是自动处理(用的多)

  3. 手动处理:将接受到的字符串进行json格式的转换let data = JSON.parse(xhr.response);

  4. 自动处理:在前面设置好响应体的数据类型:xhr.responseType = 'json';,后面直接用该数据就行

6.1 JSON.html

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>JSON响应</title><style>#result {width: 200px;height: 100px;border: solid 1px #903;}</style></head>
<body><div id="result"></div><script>// 获取元素对象const result = document.getElementById('result');// 绑定键盘按下事件window.onkeydown = function () {// 1. 创建对象const xhr = new XMLHttpRequest();// 设置响应体数据的类型(自动转换)xhr.responseType = 'json';// 2. 初始化 设置类型 与URLxhr.open('GET', 'http://127.0.0.1:8000/json-server');// 3. 发送xhr.send();// 4. 事件绑定xhr.onreadystatechange = function () {// 判断if (xhr.readyState === 4) {// 判断状态码if (xhr.status >= 200 && xhr.status < 300) {// 处理服务端返回的结果// console.log(xhr.response);// result.innerHTML = xhr.response;// 处理数据第一种方法:手动对数据转换// let data = JSON.parse(xhr.response);// result.innerHTML = data.name;// 处理数据第二种方法:自动转换console.log(xhr.response);result.innerHTML = xhr.response.name;}}}}</script>
</body>
</html>

6.2 server.js

// 1. 引入express
const express = require('express');// 2. 创建应用对象
const app = express();// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装app.all('/json-server', (request, response) => {// 设置响应头  设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');// 响应头response.setHeader('Access-Control-Allow-Headers', '*');// 响应一个数据const data = {name:'张三'};// 对对象进行字符串转换let str = JSON.stringify(data);// 设置响应体response.send(str);
});// 4. 监听端口启动服务
app.listen(8000, () => {console.log('服务已经启动, 8000 端口监听中....');
});

7. nodemon自动重启工具安装

  • 每次修改js文件都需要停掉服务重新启动,比较麻烦,这个工具会在检测到js文件修改后自动重启服务

7.1 nodemon的安装

  1. 停掉服务:ctrl + c
  2. 终端输入npm install -g nodemon进行nodemon的安装

7.2 nodemon启动服务

  1. 启动服务:nodemon server.js
  2. 后面只要该文件server.js被修改,服务会自动重新启动

8. 解决 IE 缓存问题

  • IE缓存问题:IE浏览器会对AJAX的一个请求结果做一个缓存,会导致一个问题:下一次发送请求的时候,走得是本地的缓存,而非服务器返回的最新数据,在一些时效性比较强的场景,ajax缓存会影响我们的结果,它不能够正常去显示
  • 问题:在一些浏览器中(IE),由于缓存机制的存在,ajax 只会发送的第一次请求,剩余多次请求不会在发送给浏览器而是直接加载缓存中的数据。
  • 解决方式:浏览器的缓存是根据 url 地址来记录的,所以我们只需要修改 url 地址即可避免缓存问题。我们给url后面加一个“获取当前时间的时间戳”,因为时间不同,所以url不同,浏览器会认为这是两次不同的请求,这个时候客户端会发送一个新的请求而非走本地缓存
    xhr.open("get","/testAJAX?t="+Date.now());

8.1 IE缓存问题.html

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>IE缓存问题</title><style>#result {width: 200px;height: 100px;border: solid 1px #258;}</style>
</head>
<body><button>点击发送请求</button><div id="result"></div><script>const btn = document.getElementsByTagName('button')[0];const result = document.querySelector('#result');btn.addEventListener('click', function(){console.log("test");const xhr = new XMLHttpRequest();xhr.open("GET", 'http://127.0.0.1:8000/ie?t=' + Date.now());xhr.send();xhr.onreadystatechange = function() {if (xhr.readyState === 4) {if (xhr.status >= 200 && xhr.status < 300) {result.innerHTML = xhr.response;}}}})</script>
</body>
</html>

8.2 server.js

// 1. 引入express
const express = require('express');// 2. 创建应用对象
const app = express();// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装// 针对IE缓存
app.get('/ie', (request, response) => {// 设置响应头  设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');// 设置响应体response.send('Hello IE');
});// 4. 监听端口启动服务
app.listen(8000, () => {console.log('服务已经启动, 8000 端口监听中....');
});

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

通过ajax给超时做一个设置,来及时给客户做一个提醒,并且在网络异常的时候也给用户来一个友好的提醒

  • 如果2s后还没有返回结果,就来一个提醒,告诉客户网络超时,请稍后重试
  • 如果网络异常,则返回一个提醒

9.1 超时与网络异常.html

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>超时与网络异常</title><style>#result {width: 200px;height: 100px;border: solid 1px #90b;}</style>
</head>
<body><button>点击发送请求</button><div id="result"></div><script>// 获取元素对象const btn = document.getElementsByTagName('button')[0];const result = document.getElementById('result');// 绑定事件btn.addEventListener("click", function () {// 1. 创建对象const xhr = new XMLHttpRequest();// 超时设置 2s 设置xhr.timeout = 2000;// 超时回调xhr.ontimeout = function () {result.innerHTML = "请求超时";}// 网络异常xhr.onerror = function () {alert("网络异常");}// 2. 初始化 设置类型 与URLxhr.open('GET', 'http://127.0.0.1:8000/delay');// 3. 发送xhr.send();// 4. 事件绑定xhr.onreadystatechange = function () {// 判断if (xhr.readyState === 4) {// 判断状态码if (xhr.status >= 200 && xhr.status < 300) {// 处理服务端返回的结果result.innerHTML = xhr.response;}}}})</script>
</body>
</html>

9.2 server.js

// 1. 引入express
const express = require('express');// 2. 创建应用对象
const app = express();// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装// 延时响应
app.get('/delay', (request, response) => {// 设置响应头  设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');// 延时响应setTimeout(() => {response.send('延时响应');}, 3000);
});// 4. 监听端口启动服务
app.listen(8000, () => {console.log('服务已经启动, 8000 端口监听中....');
});

9.3 断网测试

-

10. 取消请求

  • 通过代码手动取消请求
  • status:pending是处于发送过程中
  • status:cancel是取消发送

10.1 取消请求.html

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=q, initial-scale=1.0"><title>取消请求</title>
</head>
<body><button>点击发送</button><button>点击取消</button><script>// 获取元素对象const btns = document.querySelectorAll('button');let x = null;// const controller = new AbortController();btns[0].onclick = function() {const x = new XMLHttpRequest();x.open('GET', 'http://127.0.0.1:8000/cancel');x.send();}// abortbtns[1].onclick = function() {// controller.abort();x.abort();}</script>
</body>
</html>

10.2 server.js

// 1. 引入express
const express = require('express');// 2. 创建应用对象
const app = express();// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装// 取消请求
app.get('/cancel', (request, response) => {// 设置响应头  设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');// 取消请求setTimeout(() => {response.send('取消请求');}, 3000);
});// 4. 监听端口启动服务
app.listen(8000, () => {console.log('服务已经启动, 8000 端口监听中....');
});

11. 请求重复发送问题

  • 解决办法 :当点击发送第二个相同的请求的时候,把第一个请求取消掉

解决步骤:

  1. 定义一个标识变量isSending为false
  2. 修改isSending为true表示发送请求
  3. 当readyState为4的时候表示请求完成,修改isSending为false
  4. 连续发送请求,但是此时的isSending还是true,所以取消该请求重新发送
  5. 如果连续发送请求,都会取消上一个发送的请求来保证只有一个请求发出,减少服务器压力

11.1 重复请求问题.html

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=q, initial-scale=1.0"><title>取消请求</title>
</head>
<body><button>点击发送</button><script>// 获取元素对象const btns = document.querySelectorAll('button');let x = null;// 标识变量let isSending = false;  // 是否正在发送Ajax请求// const controller = new AbortController();btns[0].onclick = function() {// 判断标识变量if (isSending) x.abort();  // 如果正在发送Ajax请求,则取消请求,创建一个新的请求// 修改 标识变量的值isSending = true;x = new XMLHttpRequest();x.open('GET', 'http://127.0.0.1:8000/cancel');x.send();x.onreadystatechange = function() {if (x.readyState === 4) {// 修改标识变量isSending = false;}}}</script>
</body>
</html>

11.2 server.js

// 1. 引入express
const express = require('express');// 2. 创建应用对象
const app = express();// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装// 重复请求
app.get('/cancel', (request, response) => {// 设置响应头  设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');// 取消请求setTimeout(() => {response.send('重复请求');}, 3000);
});// 4. 监听端口启动服务
app.listen(8000, () => {console.log('服务已经启动, 8000 端口监听中....');
});

这篇关于第 2 章:AJAX 的使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1141055

相关文章

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

Redis 基本数据类型和使用详解

《Redis基本数据类型和使用详解》String是Redis最基本的数据类型,一个键对应一个值,它的功能十分强大,可以存储字符串、整数、浮点数等多种数据格式,本文给大家介绍Redis基本数据类型和... 目录一、Redis 入门介绍二、Redis 的五大基本数据类型2.1 String 类型2.2 Hash

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Linux创建服务使用systemctl管理详解

《Linux创建服务使用systemctl管理详解》文章指导在Linux中创建systemd服务,设置文件权限为所有者读写、其他只读,重新加载配置,启动服务并检查状态,确保服务正常运行,关键步骤包括权... 目录创建服务 /usr/lib/systemd/system/设置服务文件权限:所有者读写js,其他

Redis中Set结构使用过程与原理说明

《Redis中Set结构使用过程与原理说明》本文解析了RedisSet数据结构,涵盖其基本操作(如添加、查找)、集合运算(交并差)、底层实现(intset与hashtable自动切换机制)、典型应用场... 目录开篇:从购物车到Redis Set一、Redis Set的基本操作1.1 编程常用命令1.2 集

Redis中的有序集合zset从使用到原理分析

《Redis中的有序集合zset从使用到原理分析》Redis有序集合(zset)是字符串与分值的有序映射,通过跳跃表和哈希表结合实现高效有序性管理,适用于排行榜、延迟队列等场景,其时间复杂度低,内存占... 目录开篇:排行榜背后的秘密一、zset的基本使用1.1 常用命令1.2 Java客户端示例二、zse

mysql8.0.43使用InnoDB Cluster配置主从复制

《mysql8.0.43使用InnoDBCluster配置主从复制》本文主要介绍了mysql8.0.43使用InnoDBCluster配置主从复制,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录1、配置Hosts解析(所有服务器都要执行)2、安装mysql shell(所有服务器都要执行)3、

Vue3视频播放组件 vue3-video-play使用方式

《Vue3视频播放组件vue3-video-play使用方式》vue3-video-play是Vue3的视频播放组件,基于原生video标签开发,支持MP4和HLS流,提供全局/局部引入方式,可监听... 目录一、安装二、全局引入三、局部引入四、基本使用五、事件监听六、播放 HLS 流七、更多功能总结在 v