前端技术(六)—— AJAX详解

一、原生 AJAX

1. AJAX 简介

AJAX 全称为 Asynchronous JavaScript And XML,就是异步的 JS 和 XML
通过 AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据
AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。

2.XML 简介

XML 可扩展标记语言。
XML 被设计用来传输和存储数据。
XML 和 HTML 类似,不同的是 HTML 中都是预定义标签,而 XML 中没有预定义标签,全都是自定义标签,用来表示一些数据。
比如说我有一个学生数据:name = “孙悟空” ; age = 18 ; gender = “男” ;

//用 XML 表示:
<student><name>孙悟空</name><age>18</age><gender></gender>
</student>

现在已经被 JSON 取代了。

//用 JSON 表示:
{"name":"孙悟空","age":18,"gender":"男"}

3.AJAX 的特点

⑴ AJAX 的优点

  1. 可以无需刷新页面而与服务器端进行通信。
  2. 允许你根据用户事件来更新部分页面内容。

⑵ AJAX 的缺点

  1. 没有浏览历史,不能回退
  2. 存在跨域问题(同源)
  3. SEO 不友好

4. AJAX 的使用

⑴ 前期准备

1) 安装node.js

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2) 查看已安装的 Node.js 的版本号
# 打开终端,在终端输入命令 node –v 后,按下回车键,即可查看已安装的 Node.js 的版本号。
C:\Users\12137>node -v

在这里插入图片描述

Windows 系统快速打开终端的方式:
使用快捷键(Windows徽标键 + R)打开运行面板,输入 cmd 后直接回车,即可打开终端。
在这里插入图片描述

3) 使用express创建项目

使用命令初始化项目

npm init --yes

在这里插入图片描述
引入express包

npm i express

在这里插入图片描述

⑵ 核心对象

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

/*响应报文行     HTTP/1.1 200 ok头 Content-Type:text/html;charset=utf-8Content-length:2048Content-encoding:gzip体<html><head></head><body><h1>柯基侦探</h1></body></html>*/

⑶ 使用步骤

1) 创建 XMLHttpRequest 对象
var xhr = new XMLHttpRequest();
2) 设置请求信息
xhr.open(method, url);
//可以设置请求头,一般不设置
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
3) 发送请求
xhr.send(body) //get 请求不传 body 参数,只有 post 请求使用
4) 接收响应
//xhr.responseXML 接收 xml 格式的响应数据
//xhr.responseText 接收文本格式的响应数据
xhr.onreadystatechange = function (){if(xhr.readyState == 4 && xhr.status == 200){var text = xhr.responseText;console.log(text);}
}

⑷ 解决 IE 缓存问题

问题:在一些浏览器中(IE),由于缓存机制的存在,ajax 只会发送的第一次请求,剩余多次请求不会在发送给浏览器而是直接加载缓存中的数据。
解决方式:浏览器的缓存是根据 url 地址来记录的,所以我们只需要修改 url 地址即可避免缓存问题

xhr.open("get","/testAJAX?t="+Date.now());

⑸ AJAX 请求状态

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

⑹ AJAX基本的请求案例一 ——发起不带参的get请求

在这里插入图片描述
在这里插入图片描述
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端口监听中...');
});

test.html

<!DOCTYPE html>
<html lang="en">
<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>点击发送请求</button><div id="result"></div><script>//获取button元素const btn = document.getElementsByTagName('button')[0];const result = document.getElementById("result");//绑定点击事件btn.onclick = function(){//1.创建对象const xhr = new XMLHttpRequest();//2.初始化 设置请求方法和urlxhr.open('GET','http://127.0.0.1:8000/server');//3.发送xhr.send();//4.事件绑定,处理服务器返回的结果//on when 当...时候//readystate 是xhr对象中的属性,表示状态0 1 2 3 4/*readyState属性是XMLHttpRequest对象的一个重要属性,用于标识当前请求的状态。这个属性有5个可能的值,它们分别代表请求的不同阶段:‌0 - 未初始化‌:表示对象尚未调用send()方法。‌1 - 载入‌:已调用send()方法,正在发送请求。‌2 - 载入完成‌:send()方法执行完成,已经接收到全部响应内容。‌3 - 交互‌:正在解析响应内容。‌4 - 完成‌:响应内容解析完成,可以在客户端调用了。这五个状态值提供了对HTTP请求从发送到接收响应整个过程的详细跟踪,使得开发者能够更好地控制和管理异步请求。*///change 改变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;}else{}}}}</script>
</body>
</html>

测试:
启动服务
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

⑺ AJAX基本的请求案例二 —— 发起带参的get请求

ajax get请求传参可以直接在url后面拼接

url?参数1=参数1值&参数2=参数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端口监听中...');
});

test.html

<!DOCTYPE html>
<html lang="en">
<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>点击发送请求</button><div id="result"></div><script>//获取button元素const btn = document.getElementsByTagName('button')[0];const result = document.getElementById("result");//绑定点击事件btn.onclick = function(){//1.创建对象const xhr = new XMLHttpRequest();//2.初始化 设置请求方法和urlxhr.open('GET','http://127.0.0.1:8000/server?userName=zs&age=18');//3.发送xhr.send();//4.事件绑定,处理服务器返回的结果//on when 当...时候//readystate 是xhr对象中的属性,表示状态0 1 2 3 4/*readyState属性是XMLHttpRequest对象的一个重要属性,用于标识当前请求的状态。这个属性有5个可能的值,它们分别代表请求的不同阶段:‌0 - 未初始化‌:表示对象尚未调用send()方法。‌1 - 载入‌:已调用send()方法,正在发送请求。‌2 - 载入完成‌:send()方法执行完成,已经接收到全部响应内容。‌3 - 交互‌:正在解析响应内容。‌4 - 完成‌:响应内容解析完成,可以在客户端调用了。这五个状态值提供了对HTTP请求从发送到接收响应整个过程的详细跟踪,使得开发者能够更好地控制和管理异步请求。*///change 改变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;}else{}}}}</script>
</body>
</html>

测试:
启动服务
在这里插入图片描述
在这里插入图片描述

⑻ AJAX基本的请求案例三——发起不带参的post请求

在这里插入图片描述
在这里插入图片描述
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');
});app.post('/server',(request,response)=>{//设置响应//设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin','*');//设置响应体response.send('HELLO AJAX POST');
});
//4.监听端口启动服务
app.listen(8000,()=>{console.log('服务已启动,8000端口监听中...');
});

test.html

<!DOCTYPE html>
<html lang="en">
<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();//4.事件绑定xhr.onreadystatechange = function(){//判断if(xhr.readyState === 4){if(xhr.status >= 200 && xhr.status < 300){//处理服务器端返回的结果result.innerHTML = xhr.response;}}}});</script>
</body>
</html>

测试:
启动服务
在这里插入图片描述
在这里插入图片描述

⑼ AJAX基本的请求案例四 —— 发起带参的post请求

1) 发起带有请求体的post请求

在这里插入图片描述
在这里插入图片描述

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');
});app.post('/server',(request,response)=>{//设置响应//设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin','*');//设置响应体response.send('HELLO AJAX POST');
});
//4.监听端口启动服务
app.listen(8000,()=>{console.log('服务已启动,8000端口监听中...');
});

test.html

<!DOCTYPE html>
<html lang="en">
<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('username=zs&age=19');//xhr.send('username:zs&age:19');xhr.send('柯基侦探微信公众号');//4.事件绑定xhr.onreadystatechange = function(){//判断if(xhr.readyState === 4){if(xhr.status >= 200 && xhr.status < 300){//处理服务器端返回的结果result.innerHTML = xhr.response;}}}});</script>
</body>
</html>

测试:
启动服务

在这里插入图片描述

在这里插入图片描述

2) 发起带有请求头的post请求

请求报文的格式

行:POST /s?ie=uft-8 HTTP/1.1
头:Host:kejizhentan.comCookie:name=kejizhentanContent-type:application/x-www-form-urlencodedUser-Agent:chrome 83
空行:
体:username=admin&password=123456

在这里插入图片描述
在这里插入图片描述
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');
});app.post('/server',(request,response)=>{//设置响应//设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin','*');//设置响应体response.send('HELLO AJAX POST');
});
//4.监听端口启动服务
app.listen(8000,()=>{console.log('服务已启动,8000端口监听中...');
});

test.html

<!DOCTYPE html>
<html lang="en">
<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');//设置请求头xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');//3.发送请求// xhr.send('username=zs&age=19');//xhr.send('username:zs&age:19');xhr.send('柯基侦探微信公众号');//4.事件绑定xhr.onreadystatechange = function(){//判断if(xhr.readyState === 4){if(xhr.status >= 200 && xhr.status < 300){//处理服务器端返回的结果result.innerHTML = xhr.response;}}}});</script>
</body>
</html>

测试:
启动服务
在这里插入图片描述

在这里插入图片描述

⑽ AJAX基本的请求案例五 ——服务端响应json数据

1) 手动转换json数据

在这里插入图片描述
在这里插入图片描述
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');
});app.post('/server',(request,response)=>{//设置响应//设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin','*');//设置响应体response.send('HELLO AJAX POST');
});app.post('/json-server',(request,response)=>{//设置响应//设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin','*');//响应一个数据const data = {name:"柯基侦探"};//对对象进行字符串转换let str = JSON.stringify(data);//设置响应体response.send(str);
});
//4.监听端口启动服务
app.listen(8000,()=>{console.log('服务已启动,8000端口监听中...');
});

test.html

<!DOCTYPE html>
<html lang="en">
<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 #89b;}</style>
</head>
<body><div id="result"></div><script>//获取元素对象const result = document.getElementById("result");//绑定事件window.onkeydown = function(){//1.创建对象const xhr = new XMLHttpRequest();//2.初始化,设置类型与urlxhr.open('POST','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){//手动对数据进行转换let data =  JSON.parse(xhr.response);//处理服务器端返回的结果result.innerHTML = data.name;}}}}</script>
</body>
</html>

测试:
启动服务
在这里插入图片描述
在这里插入图片描述

2) 自动转换json数据

在这里插入图片描述

在这里插入图片描述
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');
});app.post('/server',(request,response)=>{//设置响应//设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin','*');//设置响应体response.send('HELLO AJAX POST');
});app.post('/json-server',(request,response)=>{//设置响应//设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin','*');//响应一个数据const data = {name:"柯基侦探"};//对对象进行字符串转换let str = JSON.stringify(data);//设置响应体response.send(str);
});
//4.监听端口启动服务
app.listen(8000,()=>{console.log('服务已启动,8000端口监听中...');
});

test.html

<!DOCTYPE html>
<html lang="en">
<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 #89b;}</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('POST','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){//处理服务器端返回的结果,自动转换json格式result.innerHTML = xhr.response.name;}}}}</script>
</body>
</html>

测试:
启动服务
在这里插入图片描述

在这里插入图片描述

⑾ nodemon自动重启工具安装

nodemon工具介绍: https://www.npmjs.com/package/nodemon

安装命令

npm install -g nodemon

在这里插入图片描述

⑿ AJAX请求超时和网络异常

在这里插入图片描述
在这里插入图片描述
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');
});app.post('/server',(request,response)=>{//设置响应//设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin','*');//设置响应体response.send('HELLO AJAX POST');
});app.post('/json-server',(request,response)=>{//设置响应//设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin','*');//响应一个数据const data = {name:"柯基侦探"};//对对象进行字符串转换let str = JSON.stringify(data);//设置响应体response.send(str);
});app.get('/delay',(request,response)=>{//设置响应//设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin','*');setTimeout(()=>{//设置响应体response.send('延迟响应~');},3000);
});
//4.监听端口启动服务
app.listen(8000,()=>{console.log('服务已启动,8000端口监听中...');
});

test.html

<!DOCTYPE html>
<html lang="en">
<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>点击发送请求</button><div id="result"></div><script>//获取button元素const btn = document.getElementsByTagName('button')[0];const result = document.getElementById("result");//绑定点击事件btn.onclick = function(){//1.创建对象const xhr = new XMLHttpRequest();//超时设置2sxhr.timeout=2000;//超时回调xhr.ontimeout = function(){alert("请求超时,请稍后重试");}//网络异常xhr.onerror = function(){alert("网络异常,家里断网啦~");}//2.初始化 设置请求方法和urlxhr.open('GET','http://127.0.0.1:8000/delay');//3.发送xhr.send();//change 改变xhr.onreadystatechange = function(){//判断(服务端返回了所有的结果)if(xhr.readyState === 4){//判断响应状态码 200 404 403 401 500//2XX 表示成功if(xhr.status >= 200 && xhr.status < 300){//处理结果 行 头 空行 体//1.响应头//设置result文本result.innerHTML = xhr.response;}else{}}}}</script>
</body>
</html>

测试:
启动服务
在这里插入图片描述
在这里插入图片描述

⒀ AJAX取消请求

在这里插入图片描述
在这里插入图片描述
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');
});app.post('/server',(request,response)=>{//设置响应//设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin','*');//设置响应体response.send('HELLO AJAX POST');
});app.post('/json-server',(request,response)=>{//设置响应//设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin','*');//响应一个数据const data = {name:"柯基侦探"};//对对象进行字符串转换let str = JSON.stringify(data);//设置响应体response.send(str);
});app.get('/delay',(request,response)=>{//设置响应//设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin','*');setTimeout(()=>{//设置响应体response.send('延迟响应~');},3000);
});
//4.监听端口启动服务
app.listen(8000,()=>{console.log('服务已启动,8000端口监听中...');
});

test.html

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

测试:
启动服务
在这里插入图片描述
在这里插入图片描述

⒁ AJAX请求重复发送问题

在这里插入图片描述
在这里插入图片描述
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');
});app.post('/server',(request,response)=>{//设置响应//设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin','*');//设置响应体response.send('HELLO AJAX POST');
});app.post('/json-server',(request,response)=>{//设置响应//设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin','*');//响应一个数据const data = {name:"柯基侦探"};//对对象进行字符串转换let str = JSON.stringify(data);//设置响应体response.send(str);
});app.get('/delay',(request,response)=>{//设置响应//设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin','*');setTimeout(()=>{//设置响应体response.send('延迟响应~');},3000);
});
//4.监听端口启动服务
app.listen(8000,()=>{console.log('服务已启动,8000端口监听中...');
});

test.html

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

测试:
启动服务
在这里插入图片描述
在这里插入图片描述

二、jQuery 中的 AJAX

1. jQuery 中 使用ajax 发送get 请求

$.get(url, [data], [callback], [type])
url:请求的 URL 地址。
data:请求携带的参数。
callback:载入成功时回调函数。
type:设置返回内容格式,xml, html, script, json, text, _default。

2. jQuery 中 使用ajax 发送 post 请求

$.post(url, [data], [callback], [type])
url:请求的 URL 地址。
data:请求携带的参数。
callback:载入成功时回调函数。
type:设置返回内容格式,xml, html, script, json, text, _default。

3.jQuery 中 使用ajax 发送请求的通用格式

$.ajax({url: 'your-endpoint-url', // 目标URLtype: 'GET', // 请求类型,可以是GET、POST、PUT、DELETE等dataType: 'json', // 预期服务器返回的数据类型data: {param1: 'value1', param2: 'value2'}, // 发送到服务器的数据beforeSend: function(xhr) {// 发送请求前可以在这里做些什么,例如设置自定义HTTP头部},success: function(response) {// 请求成功时的回调函数console.log(response);},error: function(xhr, status, error) {// 请求失败时的回调函数console.log(error);},complete: function(xhr, status) {// 请求完成时的回调函数(无论成功或失败)}
});

3. jQuery发送AJAX请求案例

在这里插入图片描述
在这里插入图片描述
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');
});app.post('/server',(request,response)=>{//设置响应//设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin','*');//设置响应体response.send('HELLO AJAX POST');
});app.post('/json-server',(request,response)=>{//设置响应//设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin','*');//响应一个数据const data = {name:"柯基侦探"};//对对象进行字符串转换let str = JSON.stringify(data);//设置响应体response.send(str);
});app.get('/delay',(request,response)=>{//设置响应//设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin','*');setTimeout(()=>{//设置响应体response.send('延迟响应~');},3000);
});app.all('/jquery-server',(request,response)=>{//设置响应//设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin','*');let data = {"usename":"柯基侦探"}response.send(JSON.stringify(data));
});
//4.监听端口启动服务
app.listen(8000,()=>{console.log('服务已启动,8000端口监听中...');
});

test.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>jQuery 发送 AJAX 请求</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
</head><body><div class="container"><h2 class="page-header">jQuery发送AJAX请求</h2><button class="btn btn-primary">GET</button><button class="btn btn-danger">POST</button><button class="btn btn-info">通用型方法</button></div><script>$('button').eq(0).click(function () {$.get("http://127.0.0.1:8000/jquery-server", { "username": "zs", "age": 18 }, function (data) {console.log(data);}, 'json');});$('button').eq(1).click(function () {$.post("http://127.0.0.1:8000/jquery-server", { "username": "zs", "age": 18 }, function (data) {console.log(data);});});$('button').eq(2).click(function () {$.ajax({url: 'http://127.0.0.1:8000/jquery-server', // 目标URLtype: 'GET', // 请求类型,可以是GET、POST、PUT、DELETE等dataType: 'json', // 预期服务器返回的数据类型data: { username: 'zhangsan', age: 18 }, // 发送到服务器的数据beforeSend: function (xhr) {// 发送请求前可以在这里做些什么,例如设置自定义HTTP头部xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');},success: function (data) {// 请求成功时的回调函数console.log("通用ajax请求响应的结果:",data);},error: function (xhr, status, error) {// 请求失败时的回调函数console.log("出错了~");},complete: function (xhr, status) {// 请求完成时的回调函数(无论成功或失败)console.log("请求完成了~");}});});</script>
</body></html>

测试:
启动服务
在这里插入图片描述
在这里插入图片描述

三、Axios发送AJAX请求

点击连接访问 https://www.bootcdn.cn/
在这里插入图片描述

1. axios 的理解和使用

⑴ axios 是什么?

  1. 前端最流行的 ajax 请求库
  2. react/vue 官方都推荐使用 axios 发 ajax 请求
  3. 文档: https://github.com/axios/axios

⑵ axios 特点

  1. 基于 xhr + promise 的异步 ajax 请求库
  2. 浏览器端/node 端都可以使用
  3. 支持请求/响应拦截器
  4. 支持请求取消
  5. 请求/响应数据转换
  6. 批量发送多个请求

⑶ axios 常用语法

axios(config): 通用/最本质的发任意类型请求的方式
axios(url[, config]): 可以只指定 url 发 get 请求
axios.request(config): 等同于 axios(config)
axios.get(url[, config]): 发 get 请求
axios.delete(url[, config]): 发 delete 请求
axios.post(url[, data, config]): 发 post 请求
axios.put(url[, data, config]): 发 put 请求
axios.defaults.xxx: 请求的默认全局配置
axios.interceptors.request.use(): 添加请求拦截器
axios.interceptors.response.use(): 添加响应拦截器
axios.create([config]): 创建一个新的 axios(它没有下面的功能)
axios.Cancel(): 用于创建取消请求的错误对象
axios.CancelToken(): 用于创建取消请求的 token 对象
axios.isCancel(): 是否是一个取消请求的错误
axios.all(promises): 用于批量执行多个异步请求
axios.spread(): 用来指定接收所有成功数据的回调函数的方法

在这里插入图片描述

2. axios 基本使用

axios(config): 通用/最本质的发任意类型请求的方式

在这里插入图片描述
在这里插入图片描述
server.js

//1.引入express
const express = require('express');
const cors = require('cors');
//2.创建应用对象
const app = express();
// 使用cors中间件
app.use(cors())
//3.创建路由规则
//request 是对请求报文的封装
//response 是对响应报文的封装
app.get('/server',(request,response)=>{//设置响应//设置响应体response.send('HELLO AXIOS GET');
});app.post('/server',(request,response)=>{//设置响应体response.send('HELLO AXIOS POST');
});app.put('/server',(request,response)=>{//设置响应体response.send('HELLO AXIOS PUT');
});app.delete('/server',(request,response)=>{//设置响应体response.send('HELLO AXIOS DELETE');
});
//4.监听端口启动服务
app.listen(8888,()=>{console.log('服务已启动,8000端口监听中...');
});

test.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>jQuery 发送 AJAX 请求</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"><script src="https://cdn.bootcdn.net/ajax/libs/axios/1.7.5/axios.js"></script>
</head><body><div class="container"><h2 class="page-header">axios基本使用</h2><button class="btn btn-primary">发送GET请求</button><button class="btn btn-danger">发送POST请求</button><button class="btn btn-info">发送PUT请求</button><button class="btn btn-info">发送DELETE请求</button></div><script>//获取按钮const btns = document.querySelectorAll('button');//模拟发送GET请求//发送GET的按钮btns[0].onclick = function(){//发送AXIOS请求axios({//请求类型method:'GET',//请求的URLurl:'http://127.0.0.1:8888/server?username=kejizhentan',}).then(response=>{console.log(response);});}//模拟发送POST请求//发送POST请求的按钮btns[1].onclick = function(){//发送axios请求axios({//请求类型method:'POST',//请求的URLurl:'http://127.0.0.1:8888/server',//设置请求体data:{username:"柯基侦探",age:7}}).then(response=>{console.log(response);});}//模拟发送PUT请求//发送PUT请求的按钮btns[2].onclick = function(){//发送axios请求axios({//请求类型method:'PUT',//请求的URLurl:'http://127.0.0.1:8888/server',//设置请求体data:{username:"张三",age:18}}).then(response=>{console.log(response);});}//模拟发送DELETE请求//发送DELETE请求的按钮btns[3].onclick = function(){//发送axios请求axios({//请求类型method:'DELETE',//请求的URLurl:'http://127.0.0.1:8888/server'}).then(response=>{console.log(response);});}</script>
</body></html>

测试:
启动服务
在这里插入图片描述
在这里插入图片描述

3. axios.request请求方式介绍

axios.request(config): 等同于 axios(config)
axios.get(url[, config]): 发 get 请求
axios.delete(url[, config]): 发 delete 请求
axios.post(url[, data, config]): 发 post 请求
axios.put(url[, data, config]): 发 put 请求

在这里插入图片描述
在这里插入图片描述
server.js

//1.引入express
const express = require('express');
const cors = require('cors');
//2.创建应用对象
const app = express();
// 使用cors中间件
app.use(cors())
//3.创建路由规则
//request 是对请求报文的封装
//response 是对响应报文的封装
app.get('/server',(request,response)=>{//设置响应//设置响应体response.send('HELLO AXIOS GET');
});app.post('/server',(request,response)=>{//设置响应体response.send('HELLO AXIOS POST');
});app.put('/server',(request,response)=>{//设置响应体response.send('HELLO AXIOS PUT');
});app.delete('/server',(request,response)=>{//设置响应体response.send('HELLO AXIOS DELETE');
});
//4.监听端口启动服务
app.listen(8888,()=>{console.log('服务已启动,8000端口监听中...');
});

test.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>jQuery 发送 AJAX 请求</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"><script src="https://cdn.bootcdn.net/ajax/libs/axios/1.7.5/axios.js"></script>
</head><body><div class="container"><h2 class="page-header">axios基本使用</h2><button class="btn btn-primary">发送GET请求</button><button class="btn btn-danger">发送POST请求</button><button class="btn btn-info">发送PUT请求</button><button class="btn btn-info">发送DELETE请求</button></div><script>//获取按钮const btns = document.querySelectorAll('button');//模拟发送GET请求//发送GET的按钮btns[0].onclick = function(){//发送AXIOS请求axios.request({//请求类型method:'GET',//请求的URLurl:'http://127.0.0.1:8888/server?username=kejizhentan',}).then(response=>{console.log(response);});}//模拟发送POST请求//发送POST请求的按钮btns[1].onclick = function(){//发送axios请求axios.post(//请求的URL'http://127.0.0.1:8888/server',//设置请求体{username:"柯基侦探",age:7}).then(response=>{console.log(response);});}//模拟发送PUT请求//发送PUT请求的按钮btns[2].onclick = function(){//发送axios请求axios({//请求类型method:'PUT',//请求的URLurl:'http://127.0.0.1:8888/server',//设置请求体data:{username:"张三",age:18}}).then(response=>{console.log(response);});}//模拟发送DELETE请求//发送DELETE请求的按钮btns[3].onclick = function(){//发送axios请求axios({//请求类型method:'DELETE',//请求的URLurl:'http://127.0.0.1:8888/server'}).then(response=>{console.log(response);});}</script>
</body></html>

测试:
启动服务
在这里插入图片描述
在这里插入图片描述

4. axios 配置对象说明

{// 请求的urlurl: '/user',//请求方法,如GET, POST, PUT, DELETE等method: 'get', // default// 设置请求的基础URLbaseURL: 'https://some-domain.com/api/',// 请求数据转换函数(可选)transformRequest: [function (data, headers) {return data;}],//响应数据转换函数(可选)transformResponse: [function (data) {return data;}],// 请求头(对象形式)headers: {'X-Requested-With': 'XMLHttpRequest'},//请求参数对象params: {ID: 12345},// 自定义参数序列化函数(可选)paramsSerializer: {//Custom encoder function which sends key/value pairs in an iterative fashion.encode?: (param: string): string => { /* Do custom operations here and return transformed string */ }, // Custom serializer function for the entire parameter. Allows user to mimic pre 1.x behaviour.serialize?: (params: Record<string, any>, options?: ParamsSerializerOptions ), //Configuration for formatting array indexes in the params. indexes: false // Three available options: (1) indexes: null (leads to no brackets), (2) (default) indexes: false (leads to empty brackets), (3) indexes: true (leads to brackets with indexes).    },//请求体数据data: {firstName: 'Fred'},// 请求超时时间(毫秒)timeout: 1000, // default is `0` (no timeout)//  是否携带凭证(如cookies)进行跨域请求(可选)withCredentials: false, // default// 自定义请求适配器(可选)adapter: function (config) {/* ... */},//基本认证凭据(用户名和密码)auth: {username: 'janedoe',password: 's00pers3cret'},//  响应数据类型,如json、arraybuffer、blob、document、text等responseType: 'json', // default// 响应数据编码,如 'utf8', 'UTF8', 'utf16le', 'UTF16LE'responseEncoding: 'utf8', // default// 用作CSRF令牌的cookie的名称xsrfCookieName: 'XSRF-TOKEN', // default// 用于放置CSRF令牌的HTTP头的名称xsrfHeaderName: 'X-XSRF-TOKEN', // default// 上传进度事件(可选)onUploadProgress: function ({loaded, total, progress, bytes, estimated, rate, upload = true}) {// Do whatever you want with the Axios progress event},// 下载进度事件(可选)onDownloadProgress: function ({loaded, total, progress, bytes, estimated, rate, download = true}) {// Do whatever you want with the Axios progress event},// 允许的最大http内容长度maxContentLength: 2000,//自定义HTTP响应状态码验证函数(可选)validateStatus: function (status) {return status >= 200 && status < 300; // default},// 最大重定向次数maxRedirects: 21, // default
}

5. axios的默认配置

Axios Config Defaults 是指通过 axios.defaults.xxx 设置 axios 的默认配置

//axios.defaults.baseURL: 设置 axios 请求的基础 URL,在发送请求时如果 URL 不是绝对路径,就会使用 baseURL。
axios.defaults.baseURL = 'https://api.example.com';
//axios.defaults.headers.common: 设置通用的请求头。
axios.defaults.headers.common['Authorization'] = 'AUTH_TOKEN';
//axios.defaults.timeout: 设置请求超时时间。
axios.defaults.timeout = 1000;
//axios.defaults.adapter: 设置自定义的请求适配器。
axios.defaults.adapter = function (config) {/* 自定义适配器的逻辑 */
};
//axios.defaults.validateStatus: 设置判定请求响应状态码的函数。
axios.defaults.validateStatus = function (status) {return status >= 200 && status < 300; // 默认的判定逻辑
};
//axios.defaults.transformRequest: 设置请求数据的转换函数。
axios.defaults.transformRequest = [function (data) {/* 转换请求数据的逻辑 */
}];
//axios.defaults.transformResponse: 设置响应数据的转换函数。axios.defaults.transformResponse = [function (data) {/* 转换响应数据的逻辑 */
}];

在这里插入图片描述
在这里插入图片描述

server.js

//1.引入express
const express = require('express');
const cors = require('cors');
//2.创建应用对象
const app = express();
// 使用cors中间件
app.use(cors())
//3.创建路由规则
//request 是对请求报文的封装
app.get('/server',(request,response)=>{console.log(request);//设置响应体response.send('HELLO AXIOS GET');
});
//4.监听端口启动服务
app.listen(8888,()=>{console.log('服务已启动,8888端口监听中...');
});

test.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>jQuery 发送 AJAX 请求</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"><script src="https://cdn.bootcdn.net/ajax/libs/axios/1.7.5/axios.js"></script>
</head><body><div class="container"><h2 class="page-header"> axios的默认配置</h2><button class="btn btn-primary">发送GET请求</button></div><script>//获取按钮const btns = document.querySelectorAll('button');//默认设置axios.defaults.method = 'GET';//设置默认的请求为getaxios.defaults.baseURL = 'http://127.0.0.1:8888';//设置基础URLaxios.defaults.params = {username:"柯基侦探"};axios.defaults.timeout=3000;//模拟发送POST请求//发送POST请求的按钮btns[0].onclick = function(){//发送axios请求axios({url:'/server'}).then(response=>{console.log(response);});}</script>
</body></html>

测试:
启动服务
在这里插入图片描述
在这里插入图片描述

6. axios创建实例对象发送请求

在这里插入图片描述
在这里插入图片描述
server.js

//1.引入express
const express = require('express');
const cors = require('cors');
//2.创建应用对象
const app = express();
// 使用cors中间件
app.use(cors())
//3.创建路由规则
//request 是对请求报文的封装
app.get('/server',(request,response)=>{console.log(request);//设置响应体response.send('HELLO AXIOS GET');
});
//4.监听端口启动服务
app.listen(8888,()=>{console.log('服务已启动,8888端口监听中...');
});

test.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>jQuery 发送 AJAX 请求</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"><script src="https://cdn.bootcdn.net/ajax/libs/axios/1.7.5/axios.js"></script>
</head><body><div class="container"><h2 class="page-header"> axios创建实例对象发送请求</h2><button class="btn btn-primary">发送GET请求</button></div><script>//获取按钮const btns = document.querySelectorAll('button');//创建实例对象const kjzt = axios.create({baseURL: 'http://127.0.0.1:8888',timeout: 2000});//这里的kjzt对象跟axios对象几乎是一样的功能btns[0].onclick = function () {kjzt({//请求类型method:'GET',url: '/server'}).then(response => {console.log(response);});} </script>
</body></html>

测试:
启动服务
在这里插入图片描述
在这里插入图片描述

7. axios拦截器

在这里插入图片描述
在这里插入图片描述
server.js

//1.引入express
const express = require('express');
const cors = require('cors');
//2.创建应用对象
const app = express();
// 使用cors中间件
app.use(cors())
//3.创建路由规则
//request 是对请求报文的封装
app.get('/server',(request,response)=>{console.log(request);//设置响应体response.send('HELLO AXIOS GET');
});
//4.监听端口启动服务
app.listen(8888,()=>{console.log('服务已启动,8888端口监听中...');
});

test.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>jQuery 发送 AJAX 请求</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"><script src="https://cdn.bootcdn.net/ajax/libs/axios/1.7.5/axios.js"></script>
</head><body><div class="container"><h2 class="page-header"> axios创建实例对象发送请求</h2><button class="btn btn-primary">发送GET请求</button></div><script>//设置请求拦截器axios.interceptors.request.use(function (config) {console.log('请求拦截器 成功 -1!');return config;}, function (error) {console.log('请求拦截器 失败-1!');return Promise.reject(error);});//设置请求拦截器axios.interceptors.request.use(function (config) {console.log('请求拦截器 成功-2!');return config;}, function (error) {console.log('请求拦截器 失败-2!');return Promise.reject(error);});// 设置响应拦截器axios.interceptors.response.use(function (response) {console.log('响应拦截器 成功-1!');return response;}, function (error) {console.log('响应拦截器 失败-1!');return Promise.reject(error);});// 设置响应拦截器axios.interceptors.response.use(function (response) {console.log('响应拦截器 成功-2!');return response;}, function (error) {console.log('响应拦截器 失败-2!');return Promise.reject(error);});//发送请求//获取按钮const btns = document.querySelectorAll('button');//模拟发送GET请求//发送GET的按钮btns[0].onclick = function(){//发送AXIOS请求axios({//请求类型method:'GET',//请求的URLurl:'http://127.0.0.1:8888/server',}).then(response=>{console.log('自定义回调处理成功的结果!');}).catch(response=>{console.log('自定义回调处理失败的结果');});}</script>
</body></html>

测试:
启动服务
在这里插入图片描述
在这里插入图片描述

  1. 说明: 调用 axios()并不是立即发送 ajax 请求, 而是需要经历一个较长的流程
  2. 流程: 请求拦截器2 => 请求拦截器1 => 发ajax请求 => 响应拦截器1 => 响
    应拦截器 2 => 请求的回调
  3. 注意: 此流程是通过 promise 串连起来的, 请求拦截器传递的是 config, 响应
    拦截器传递的是 response

8. axios取消请求

⑴ 基本流程

配置 cancelToken 对象
缓存用于取消请求的 cancel 函数
在后面特定时机调用 cancel 函数取消请求
在错误回调中判断如果 error 是 cancel, 做相应处理

⑵ 实现功能

点击按钮, 取消某个正在请求中的请求,在请求一个接口前, 取消前面一个未完成的请求

⑶ axios取消请求和防止重复请求的案例

在这里插入图片描述
在这里插入图片描述
server.js

//1.引入express
const express = require('express');
const cors = require('cors');
//2.创建应用对象
const app = express();
// 使用cors中间件
app.use(cors())
//3.创建路由规则
//request 是对请求报文的封装
app.get('/server',(request,response)=>{console.log(request);//设置延迟三秒后响应setTimeout(()=>{//设置响应体response.send('HELLO AXIOS GET');},3000);
});
//4.监听端口启动服务
app.listen(8888,()=>{console.log('服务已启动,8888端口监听中...');
});

test.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>jQuery 发送 AJAX 请求</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"><script src="https://cdn.bootcdn.net/ajax/libs/axios/1.7.5/axios.js"></script>
</head><body><div class="container"><h2 class="page-header"> axios创建实例对象发送请求</h2><button class="btn btn-primary">发送GET请求</button><button class="btn btn-danger">取消请求</button></div><script>//获取按钮const btns = document.querySelectorAll('button');//2.声明全局变量let cancel = null;//发送请求btns[0].onclick = function () {//检测上一次请求是否已完成if(cancel !== null){//取消上一次的请求cancel();}axios({method: 'GET',url: 'http://127.0.0.1:8888/server',//1.添加配置对象的属性cancelToken: new axios.CancelToken(c => {//3.将参数赋值给全局变量cancelcancel = c;})}).then(response => {console.log(response);//将cancel 的值初始化cancel = null;});}//给第二个按钮 绑定取消请求btns[1].onclick = function () {cancel();}</script>
</body></html>

测试:
启动服务
在这里插入图片描述
在这里插入图片描述

四、跨域

1. 同源策略

同源策略(Same-Origin Policy)最早由 Netscape 公司提出,是浏览器的一种安全策略。
同源: 协议、域名、端口号 必须完全相同。
违背同源策略就是跨域。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大语言模型(LLM)如何更好地继续预训练(Continue PreTraining)

预训练&#xff08;Pretraining&#xff09;是一个非常消耗资源的工作&#xff0c;尤其在 LLM 时代。随着LLama2的开源&#xff0c;越来越多人都开始尝试在这个强大的英文基座模型上进行中文增强。但&#xff0c;我们如何才能保证模型在既学到「中文知识」的情况下&#xff0c;…

灰光模块,彩光模块-介绍

1. 引用 知识分享系列一&#xff1a;5G基础知识-CSDN博客 5G前传的最新进展-CSDN博客 灰光和彩光_通信行业5G招标系列点评之二&#xff1a;一文读懂5G前传-光纤、灰光、彩光、CWDM、LWDM、MWDM...-CSDN博客 ADOP带你了解&#xff1a;CWDM、DWDM、MWDM、LWDM&#xff1a;快速…

网络编程day03(网络体系结构、调试命令、TCP/IP对比)

目录 1》网络的体系结构 1> OSI模型 2> TCP/IP模型 3> 常见网络协议 4> DNS域名解析协议 2》 网络调试命令 1> ping&#xff1a;测试网络连通性&#xff08;ICMP&#xff09; 2> netstat 3》Dos &#xff08;拒绝式服务&#xff09;攻击&#xff1f;…

【大模型-RAG】RAG最佳实践论文及项目解读

文章目录 论文概述RAG工作流程核心代码解读软件架构查询引擎构建数据加载与索引创建微调嵌入模型 项目应用结论 在人工智能领域&#xff0c;大型语言模型&#xff08;LLMs&#xff09;因其强大的文本生成能力而备受关注。然而&#xff0c;这些模型在生成信息时可能会产生过时的…

代码随想录:96. 不同的二叉搜索树

96. 不同的二叉搜索树 class Solution { public:int numTrees(int n) {int dp[30]{0};//由i个结点组成的二叉搜索树有多少种dp[0]1; for(int i1;i<n;i)for(int j0;j<i;j)//j表示根节点左子树有j个结点dp[i]dp[j]*dp[i-j-1];//对根节点左右子树结点数量遍历//数量有左子树…

什么是数据结构三要素?

目录 1.逻辑结构 2.数据的存储结构 3.数据的运算 1.逻辑结构 逻辑结构是指数据元素之间的逻辑关系&#xff0c;即从逻辑关系上描述数据。 它与数据的存储无关&#xff0c;是独立于计算机的。数据的逻辑结构非为线性结构和非线性结构&#xff0c;线性表是典型的线性结构&am…

ELK学习笔记——如何给Kibana新增用户和角色

Kibana新增用户和角色 首先用超管账号登录上Kibana&#xff0c;按照下面步骤操作 1、创建角色 按图操作 2、创建用户 按图操作 3、给用户分配角色 至此&#xff0c;角色和用户绑定成功&#xff1b; 最后&#xff0c;可以退出管理员账号&#xff0c;登录这个新…

【MATLAB】FIR滤波器的MATLAB实现

FIR滤波器的MATLAB实现 FIR滤波器的设计fir1函数fir2函数 与IIR滤波器相比&#xff0c;FIR滤波器既有其优势也有其局限性。FIR滤波器的主要优点包括&#xff1a; 精确的线性相位响应&#xff1b;永远保持稳定性&#xff1b;设计方法通常是线性的&#xff1b;在硬件实现中具有更…

Django学习实战篇二(适合略有基础的新手小白学习)(从0开发项目)

前言&#xff1a; 从这一章开始&#xff0c;我们来创建项目typeidea&#xff0c;我把它放到了GitHub上。强烈建议你也到GitHub上注册一个账号&#xff08;如果没有的话&#xff09;&#xff0c;然后创建这样的项目。当然&#xff0c;你也可以起一个属于自己的名称。这个项目就是…

Live800:以客户为中心,重塑服务标准

在快速迭代的商业环境中&#xff0c;企业若想持续繁荣&#xff0c;就必须不断审视并优化自身的服务模式。传统上&#xff0c;服务往往被视为产品交易的附加品&#xff0c;但今日之市场&#xff0c;服务已悄然成为企业核心竞争力的关键要素。因此&#xff0c;“以客户为中心&…

5、Django Admin后台移除“删除所选”操作

默认情况下&#xff0c;Django Admin后台的listview模型列表页&#xff0c;会有一个Delete Selected删除所选操作。假设你需要再从Hero管理模型中移除该删除操作。 ModelAdmin.get_actions方法可以返回所有的操作方法。通过覆盖此方法&#xff0c;移除其中delete_selected方法…

美团面试:mysql 索引失效?怎么解决? (重点知识,建议收藏,读10遍+)

美团面试&#xff1a;mysql 索引失效&#xff1f;怎么解决&#xff1f; 尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、shein 希音、shopee、百度、网易的面试资格&#xff0c;遇到很多很…

MacTalk 测评通义灵码,如何实现“微信表情”小功能?

作者&#xff1a;池建强&#xff0c;墨问西东创始人 前段时间&#xff0c;我写了篇墨问研发团队放弃 GitHub Copilot 的文章&#xff0c;没想到留言区一些读者推荐我们试试通义灵码&#xff0c;说它效果很不错。我呢&#xff0c;一直没腾出时间折腾。 直到月中时&#xff0c;…

Java之线程篇一

目录 如何理解进程&#xff1f; 进程和线程的区别 线程的优点 线程的缺点 线程异常 线程用途 创建线程 方法一&#xff1a;继承Thread类&#xff0c;重写run() 观察线程 小结 方法二&#xff1a; 实现Runnable接口&#xff0c;重写run() 方法三&#xff1a;继承Threa…

k8s之HPA实践——实现Web服务器的自动伸缩特性

文章目录 在生产环境中&#xff0c;总会有一些意想不到的事情发生&#xff0c;比如公司网站流量突然升高&#xff0c;此时之前创建的Pod已不足以支撑所有的访问&#xff0c;而运维人员也不可能24小时守着业务服务&#xff0c;这时就可以通过配置HPA&#xff0c;实现负载过高的情…

AI时代来临,AI基础数据服务行业未来发展有哪些变化

AI基础数据服务是针对人工智能&#xff08;AI&#xff09;领域提供的一项服务&#xff0c;它包括数据采集、数据清洗、信息抽取和数据标注等服务。AI基础数据服务旨在为AI算法的训练和优化提供必要的数据支持&#xff0c;为AI算法的性能提供保障。 标贝科技提供专业的数据采集、…

写的一致性问题之双写模式

文章目录 1、先写mysql&#xff1a;mysql会回滚&#xff0c;而redis不会回滚2、先写redis&#xff1a; 1、先写mysql&#xff1a;mysql会回滚&#xff0c;而redis不会回滚 写入msql成功&#xff0c;写入redis也成功&#xff0c;但是后续事务提交失败&#xff0c;mysql会回滚&a…

自己开发完整项目一、登录功能-04(集成jwt)

一、说明 前面文章我们写到了通过数据库查询出用户信息并返回&#xff0c;那么在真实的项目中呢&#xff0c;后端是需要给前端返回一个tocken&#xff0c;当前端通过登录功能认证成功之后&#xff0c;我们后端需要将用户信息和权限整合成一个tocken返回给前端&#xff0c;当前端…

硬盘数据恢复的正确姿势,这4款神器让你2024年秒变IT达人

现在&#xff0c;数据对我们超级关键&#xff0c;干啥都缺不了。但要是数据没了或者手一滑给删了&#xff0c;那可真够呛。甭管是点错了、电脑故障还是硬件磕了碰了&#xff0c;数据丢了可是大麻烦。不过幸亏科技一直在进步&#xff0c;硬盘数据恢复的技术也越来越厉害&#xf…

最近大模型最火的就业方向有哪些?

在2023和2024年&#xff0c;大语言模型的发展迎来了绝对风口&#xff0c;吸引了大量创业者和投资者。然而&#xff0c;经过一年的发展&#xff0c;许多公司已经销声匿迹。那么&#xff0c;未来大模型方向上还有哪些可以继续发展的方向呢? 基座大模型预训练 现状 - 展现出“胜…