- Ajxax(Asynchronous JavaScript and XML,异步的JavaScriopt和XML)是一种可以用于创建动态web应用的技术
- 前端需要在文件终端中先配置文件,后端则是要创建一个服务器从而让前端进行访问
- 前端需要后端提供的RUL 从而创建ajax进行交互
- 控制台内的网络查看
- 检查窗口可以汉化
设置后重启网页就可以了
查看网络面板
状态码补充
详情链接 blog.csdn.net/weixin_6314…
- Ajax四步
- 1首先要创建一个xhr对象
let xhr=new XMLHttpRequest- 2监听成功的响应(服务器成功响应了数据,会触发load事件)
xhr.onload=()=>{}- 3 设置请求(请求有三个参数
- 1.请求方式(get post put delete head)2.请求URL(http://127.0.0.1:3000/XXX) 3.是否异步,默认是异步)
xhr.open('get','http://127.0.0.1:3000/XXX')- 4发出请求 发出请求时,可以给服务器传递参数 send(请求体)
xhr.send()-
用url把数据上传到服务器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>通过url把数据扔给服务器</h1>
<hr>
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username" id="username"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="pwd" id="pwd"></td>
</tr>
<tr>
<td></td>
<td>
<button id="btn">GET方式提交</button>
</td>
</tr>
</table>
<script>
const btn = document.querySelector('#btn');
const username = document.querySelector('#username');
const pwd = document.querySelector('#pwd');
const xhr = new XMLHttpRequest();
xhr.onload = () => {
alert(xhr.responseText);
};
btn.onclick = () => {
// 拼接查询字符串
const qs = `uername=${username.value}&pwd=${pwd.value}`
xhr.open("get","/getData?"+qs)
xhr.send();
}
</script>
</body>
</html>
测试效果如下
网络面板补充
通过请求体吧数据扔给服务器
- get请求只能通过url把数据扔给服务器,post.put请求不仅可以把通过url把数据扔给服务器,也可以通过请求体把数据扔给服务器.扔给服务器的数据也是有多个格式的
- text/plain
- 默认的请求体类型,如果不设置请求头字段Content-type,默认就是这种类型
- 请求体只要是字符串就可以,后端不会做任何处理
- application/x-www-form-urlencoded
- 需要设置请求头xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded')
- 要求请求体是查询字符串如 a=100&b=200
- 点击提交按钮提交表单(非Ajax),如果Method是Post的话,默认请求体内容就是x-www-from-urlencoded
- application/json
- 设置请求头xhr.setRequestHeader('Content-type','application/json')
- 要求请求体是json格式的字符串
- multipart/form-data
-演示form-data后端代码
// 导入模块
const path = require('path');
const express = require('express');
const bodyParser = require('body-parser'); // body-parser 专门用于接收请求体数据
const multer = require('multer');
// 创建 express 实例
const app = express();
// 挂载中间件处理请求体
app.use(bodyParser.text());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.get("/",(req,res)=>{
res.sendFile(path.join(__dirname,"../client","index.html"))
})
// req.body 就可以获取请求体中的数据
// typeof req.body 查看接收到的数据是什么类型
// res.send('POST 方式提交成功!'); 响应数据
// req.query 得到url传递的参数的
// req.headers['content-type'] 得到请求头
app.post('/getData', (req, res) => {
console.log('接收到 POST 请求:')
console.log('URL中获取的信息:', req.query);
console.log('请求体内容类型:', req.headers['content-type']);
console.log('请求体中获取的信息:', req.body, typeof req.body);
console.log('');
res.send('POST 方式提交成功!');
});
app.listen(3000,()=>{
console.log('服务器启动了,端口是3000');
})
- 前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>通过url把数据扔给服务器</h1>
<hr>
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username" id="username"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="pwd" id="pwd"></td>
</tr>
<tr>
<td></td>
<td>
<button id="btn">POST方式提交</button>
</td>
</tr>
</table>
<script>
const btn = document.querySelector('#btn');
const username = document.querySelector('#username');
const pwd = document.querySelector('#pwd');
const xhr = new XMLHttpRequest();
xhr.onload = () => {
alert(xhr.responseText);
};
btn.onclick = () => {
// ?a=1&b=2 url 传参
xhr.open("post","/getData?a=1&b=2")
const qs = `uername=${username.value}&pwd=${pwd.value}`
// send中写请求体 send(qs); 叫请求体传参
xhr.send(qs);
}
</script>
</body>
</html>
- 后端效果
浏览器效果
- 演示 application/x-www-form-urlencoded,后端同上。
- 前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>通过url把数据扔给服务器</h1>
<hr>
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username" id="username"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="pwd" id="pwd"></td>
</tr>
<tr>
<td></td>
<td>
<button id="btn">POST方式提交</button>
</td>
</tr>
</table>
<script>
const btn = document.querySelector('#btn');
const username = document.querySelector('#username');
const pwd = document.querySelector('#pwd');
const xhr = new XMLHttpRequest();
xhr.onload = () => {
alert(xhr.responseText);
};
btn.onclick = () => {
// ?a=1&b=2 url 传参
xhr.open("post","/getData?a=1&b=2")
const qs = `uername=${username.value}&pwd=${pwd.value}`
// 在发请求之前,设置请求头,设置的头,叫Content-Type
// 请求头一定要在 open() 之后,send() 之前设置
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
// send中写请求体 send(qs); 叫请求体传参
xhr.send(qs);
}
</script>
</body>
</html>
- 后端效果
- 浏览器效果
- 演示 application/json,后端同上。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>通过url把数据扔给服务器</h1>
<hr>
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username" id="username"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="pwd" id="pwd"></td>
</tr>
<tr>
<td></td>
<td>
<button id="btn">POST方式提交</button>
</td>
</tr>
</table>
<script>
const btn = document.querySelector('#btn');
const username = document.querySelector('#username');
const pwd = document.querySelector('#pwd');
const xhr = new XMLHttpRequest();
xhr.onload = () => {
alert(xhr.responseText);
};
btn.onclick = () => {
// ?a=1&b=2 url 传参
xhr.open("post","/getData?a=1&b=2")
// 如果传递的格式是application/json 那么就不再是x=y&z=s
const data = { username:username.value, pwd:pwd.value }
// 请求头一定要在 open() 之后,send() 之前设置
xhr.setRequestHeader('Content-type', 'application/json');
// send中写请求体 send(qs); 叫请求体传参
// 传递时,需要把JSON对象,手动转化成JSON字符串
xhr.send(JSON.stringify(data));
}
</script>
</body>
</html>
- 后端效果
- 浏览器效果
- Ajax可以发送请求,form默认模式也可以发送请求
通过formData传递数据
- 请求体(send())的方法参数 除了是字符串,也可以是formData对象.如果是formData对象浏览器会自动设置请求头字段Content-type为 multipart-data.
- formData不仅可以传递普通数据,还可以上传文件
- 后端代码演示
// 导入模块
const path = require('path');
const express = require('express');
const bodyParser = require('body-parser'); // body-parser 专门用于接收请求体数据
const multer = require('multer');
// 创建 express 实例
const app = express();
// 挂载中间件处理请求体
app.use(bodyParser.text());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.get("/",(req,res)=>{
res.sendFile(path.join(__dirname,"../client","index.html"))
})
// req.body 接收前端传递过来的普通数据
// req.file 接收前端上传过来的文件
const upload = multer({ dest: 'uploads/' })
app.post('/upload',upload.single('avator'),(req, res) => {
console.log('文件上传成功:');
console.log('文件信息:', req.file);
console.log('表单数据:', req.body);
console.log('');
res.send('文件上传成功!');
});
app.listen(3000,()=>{
console.log('服务器启动了,端口是3000');
})
- 前端代码演示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>通过formdata把数据扔给服务器</h1>
<hr>
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username" id="username"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="pwd" id="pwd"></td>
</tr>
<tr>
<td></td>
<td>
<button id="btn1">提交1</button>
</td>
</tr>
</table>
<script>
const username = document.querySelector("#username")
const pwd = document.querySelector("#pwd")
const btn1 = document.querySelector("#btn1")
const xhr = new XMLHttpRequest();
xhr.onload = () => {
alert(xhr.responseText);
};
btn1.onclick = () => {
// 创建FormData fd是一个对象 容器
const fd = new FormData();
fd.append("username",username.value)
fd.append("pwd",pwd.value)
fd.append("aaaa",1111)
fd.append("bbbb",2222)
xhr.open('POST', '/upload');
// send中不只可以放字符串,还可以放formdata对象
xhr.send(fd);
}
</script>
</body>
</html>
测试
- 现在这个请求头是默认的请求头,并没有设置.还有一种写法
响应报文
<script>
const xhr = new XMLHttpRequest();
xhr.onload = function(){
// 响应分三部分:
// 响应行
console.log("响应行:")
console.log('响应状态码:', xhr.status);
console.log('响应状态描述:', xhr.statusText);
console.log('');
// 响应头
console.log('响应头:');
console.log('Content-type:', xhr.getResponseHeader('Content-type'));
console.log('Date:', xhr.getResponseHeader('Date'));
console.log(xhr.getAllResponseHeaders());
console.log('');
// 响应体
console.log('响应体:')
console.log(xhr.response);
console.log(xhr.responseText);
}
const btn = document.querySelector("#btn");
btn.onclick = ()=>{
xhr.open("get","/getData")
// get请求没有请求体,null是空的意思
xhr.send(null);
}
</script>
响应JSON
<script>
const xhr = new XMLHttpRequest();
// 设置期望的响应数据的数据类型,期望服务器响应json
// xhr.responseText 这个API就不能使用了
xhr.responseType = "json";
xhr.onload = function () {
// console.log(JSON.parse(xhr.responseText));
// xhr.response得到服务器响应的JSON数据 不需要通过JSON.parse
console.log(xhr.response);
}
const btn = document.querySelector("#btn");
btn.onclick = () => {
// 请求同一个url,第一次不走缓存,
// 从第二次开始,就可能走缓存,304表示走的缓存
// 不想走缓冲,需要让每次请求的url不一样
// xhr.open("get", "/getData?random="+Math.random())
xhr.open("get", "/getData?xx="+Date.now())
xhr.send(null);
}
</script>
超时处理
<script>
const xhr = new XMLHttpRequest();
xhr.responseType = "json";
xhr.onload = function () {
console.log(xhr.response);
}
// 设置超时时间 5s
// 如果时间到了,数据还没有回来,会自动取消请求
xhr.timeout = 5000;
const btn = document.querySelector("#btn");
btn.onclick = () => {
xhr.open("get", "/getData?xx="+Date.now())
xhr.send(null);
}
const btn2 = document.querySelector("#btn2");
btn2.onclick = () => {
xhr.abort(); // 取消请求~
}
</script>
Ajax的总结
首先创建xhr对象,使用构造函数 XMLHttpRequest 就可以创建一个 XHR 对象。
let xhr = new XMLHttpRequest();
ajax对象中的属性:
| 属性名 | 含义 |
|---|---|
| readyState | 返回一个数字,表示请求的状态: 0 -- UNSET -- XHR对象已创建或已被 abort() 方法重置。 1 -- OPENDED -- open() 方法已经被调用。 2 -- HEADERS_RECEIVED -- send() 方法已经被调用,并且响应头和响应状态已经可获得。 3 -- LOADING -- 下载中, responseText 属性已经包含部分数据。 4 -- DONE -- 所有响应数据接收完毕。 |
| status | 响应状态码,如 404、200 等。 |
| statusText | 响应状态码的文本描述,如 200 对应的是 “OK”。 |
| responseXML | 接收格式为 XML 的响应数据,返回一个 document 对象。 |
| responseText | 获取响应文本,返回一个字符串。 |
| responseType | 用于设置响应内容的类型 xhr2 |
| response | 返回的类型取决于 responseType 的设置。 xhr2 |
| timeout | 设置超时时间。xhr2 |
| ajax对象中的方法如下: |
| 方法名 | 含义 |
|---|---|
| open() | 初始化 HTTP 请求,用来指定请求方式和 URL。 xhr.open(method, url, [async], [user], [password]) |
| send() | 发送 HTTP 请求,参数可以设置请求体,没有请求体无需设置参数。 |
| setRequestHeader() | 设置 HTTP 请求头的值。必须在 open() 之后、send() 之前调用。 |
| abort() | 如果请求已被发出,则立刻中止请求。 |
| getAllResponseHeaders() | 以字符串形式返回所有的响应头。 |
| getResponseHeader() | 返回指定的响应头。 |
| jax对象中的事件: | |
| 事件名 | 含义 |
| ---------------- | --------------------------------------------------- |
| readystatechange | readyState 属性值发生变化触发该事件。 |
| abort | 请求终止时触发。 |
| error | 请求遇到错误时触发。 |
| loadstart | 接收到响应数据时触发。 |
| load | 请求成功完成时触发。 |
| loaded | 当请求结束时触发, 无论请求成功 ( load) 还是失败 (abor 或 error)。 |
| progress | 当请求接收到更多数据时,周期性地触发。 |
| timeout | 在预设时间内没有接收到响应时触发。 |
异步请求:
- 在发请求之后,其他同步任务都已经执行完毕了 同步请求:
-
- 在发请求之后,需要等到响应完全结束后才会执行剩下同步任务。 默认情况下,ajax发的请求都是异步的,可以通过open方法中的第三个参数设置为同步请求
- true 表示请不请求,默认是true
- false 表示同步请求 基本上用不到 跨域 cors 总结
- 源:协议+域名+端口
- 同源:相同的协议&相同的域名&相同的端口
- 不同源:不同的协议或不同的域名或不同的端口
JSONP
不受同源策略的限制 -资源的引入 如 img标签的src link标签的href script标签中的src -页面中a标签中的href -表单的提交 -重定向页面 发送http请求的方式:
- 浏览器的地址栏,只能发送get请求
- postman软件,可以各种请求,类似postman这样的软件有很多
- html中有些标签也会发请求,如img, link, script, a, form....
- ajax可以发各位请求,最大的特点:局部刷新,提升用户体验
- ..... JSONP不同于ajax,jsonp发请求本质是利用script标签的src发的请求
<script>
let btn = document.querySelector("#btn");
// jsonp的原理
function jsonp(options) {
let callName = "fn";
// data就是服务器响应的数据
window[callName] = function (data) {
console.log("fn函数执行了....");
if (data != null) {
options.success(data)
} else {
options.fail();
}
}
// 利用script标签的src发请求,没有跨域问题
// "fn(JSON.stringify({a:1,b:2}))"
let url = options.url + "?callBack=" + callName
let scriptEle = document.createElement("script");
scriptEle.src = url;
document.body.append(scriptEle)
}
btn.onclick = function () {
jsonp({
url: "http://127.0.0.1:3000/",
success: function (data) {
console.log("data:", data);
},
fail: function (err) {
console.log("数据请求失败了");
}
})
}
</script>
Fetch
Fetch API 被设计用来取代 XMLHttpRequest,它提供了许多与 XMLHttpRequest 相同的功能,但被设计成更具可扩展性和高效性。
Fetch API 的主要特点包括:
- Promise 风格的 API:Fetch API 提供了 Promise 风格的 API,可以更加方便地处理异步请求和响应。
- 更加灵活的请求和响应:Fetch API 可以发送任何类型的请求,包括 GET、POST、PUT、DELETE 等,也可以接收任何类型的响应,包括文本、JSON、二进制数据等。
- 更加强大的响应处理:Fetch API 提供了一系列的响应处理方法,包括 json()、text()、blob()、arrayBuffer() 等,可以更加方便地处理响应数据。
<script>
let btn1 = document.querySelector("#btn1");
let btn2 = document.querySelector("#btn2");
let btn3 = document.querySelector("#btn3");
let btn4 = document.querySelector("#btn4");
// get请求
btn1.onclick = function(){
// fetch方法返回 pormise对象
// let p = fetch("http://httpbin.org/get?a=1");
// console.log(p) // Promise padding
fetch("http://httpbin.org/get?a=1").then(res=>{
console.log("--res:",res)
})
}
btn2.onclick = function(){}
btn3.onclick = function(){}
btn4.onclick = function(){}
</script>
发送get请求
btn1.onclick = async function () {
try {
const res = await fetch("http://httpbin.org/get?a=1")
const data = await res.json();
console.log(data);
} catch (reason) {
console.log('请求失败!', reason);
}
}
btn2.onclick = function () { }
btn3.onclick = function () { }
btn4.onclick = function () { }
Axios介绍 Axios 是前端最流行的 ajax 请求库 ,没有之一,react、vue官方都推荐使用 的 Ajax 请求库。
- 官方网站:axios-http.com
- 仓库地址:github.com/axios/axios
- 中文文档:axios-http.com/zh/docs/int…
axios特点
- 基于 XMLHttpRequest + Promise 的异步的 Ajax 请求库
- 浏览器端、Node端都可以使用
- 支持请求和响应拦截器
- 支持请求取消
- 批量发送多个请求
- 支持请求与响应的数据转换(二次封装)
先在终端中使用npm install axios下载
下载后在页面引入或者直接使用 CDN
<script src="axios脚本文件地址"></script>Axios的基本使用 - axios(config): 通用/最本质的发送意类型请求的方式。
- axios(url[, config]): 第一个参数是地址,第二个参数是配置项。
- 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.patch(url[, data[, config]]) 发送patch请求
<script>
const btn = document.querySelector("#btn");
btn.onclick = async function(){
// 使用方式一 axios函数使用一个对象作为参数
// axios({
// method:"GET",
// url:'https://tenapi.cn/v2/toutiaohot'
// }).then(res => {
// console.log(res);
// }).catch(reason => {
// console.log('请求失败!', reason);
// });
// 使用方式二 第一个参数是url,第二个参数是请求配置对象
// axios("/toutiaohot",{
// method:"GET",
// baseURL:"https://tenapi.cn/v2",
// timemout:5000
// }).then(res => {
// console.log(res);
// }).catch(reason => {
// console.log('请求失败!', reason);
// });
// 使用方式三 axios.request() 方法同 axios 本身
// axios.request("/toutiaohot",{
// method:"GET",
// baseURL:"https://tenapi.cn/v2",
// timemout:5000
// }).then(res => {
// console.log(res);
// }).catch(reason => {
// console.log('请求失败!', reason);
// });
// 使用方式四 axios.get() axios.post()
// axios.get("/toutiaohot",{
// baseURL:"https://tenapi.cn/v2",
// timemout:5000
// }).then(res => {
// console.log(res);
// }).catch(reason => {
// console.log('请求失败!', reason);
// });
// 使用方式五 async await 方式
// const res = await axios.get("/toutiaohot",{
// baseURL:"https://tenapi.cn/v2",
// timemout:5000
// })
const res = await axios.get("https://tenapi.cn/v2/toutiaohot")
console.log(res);
}
</script>
Axios请求配置项 我系统用不来了,跳过 Axios创建实例
前面使用的axios,是默认的实例(axios函数),引入axios.js,就有默认的实例。前面我们讲了,可以给这个默认实例作一些配置。当给该实例设置一些默认配置时, 这些配置就被固定下来了,但是后续开发中, 某些配置可能会不太一样,比如,我们要向两台服务器发出请求,如下:
代码演示
<script>
const btn1 = document.querySelector("#btn1");
const btn2 = document.querySelector("#btn2");
// 创建axios实例,参数是请求配置对象
const bizhiInstance = axios.create({
baseURL:"https://v2.api-m.com",
timeout: 5000
})
const yiyanInstance = axios.create({
baseURL:"https://tenapi.cn",
timeout: 5000
})
btn1.onclick = async function () {
bizhiInstance.get("/api/wallpaper",{params:{a:1}}).then(res => {
console.log('获取壁纸成功~',res.data);
}) .catch(reason => {
console.log('获取壁纸失败~',reason);
})
}
btn2.onclick = async function () {
yiyanInstance.get("/v2/yiyan",{params:{a:1}}).then(res => {
console.log('获取一言成功~',res);
}) .catch(reason => {
console.log('获取一言失败~',reason);
})
}
</script>
Axios取消请求 流程:
- 请求配置项中配置 cancelToken 对象
- 用变量保存用于取消请求的 cancel 函数
- 在后面特定时机调用 cancel 函数实现取消请求
- 在错误回调中判断如果 error 是 cancel, 做相应处理
<script>
const btn1 = document.querySelector("#btn1");
const btn2 = document.querySelector("#btn2");
// 定义定义变量,保存取消请求的函数,当需要取消请求的时候调用该函数
let cancelFn = null;
// 发送请求
btn1.onclick = async function () {
axios.get("https://tenapi.cn/v2/yiyan",{
cancelToken: new axios.CancelToken((cb)=>{
console.log("xxxxxxx")
console.log(cb) // 取消请求的 cancel 函数
cancelFn = cb;
})
}).then(res => {
console.log('获取一言成功~',res);
}) .catch(reason => {
console.log('获取一言失败~',reason);
})
}
btn2.onclick = async function () {
cancelFn();
}
</script>
批量处理响应
<script>
const btn1 = document.querySelector("#btn1");
// 全局配置
axios.defaults.baseURL = "https://v2.api-m.com";
btn1.onclick = async function () {
// 写了axios.get,表示请求已经发出去了
const res1 = axios.get("https://v2.api-m.com/api/wallpaper")
const res2 = axios.get("https://v2.api-m.com/api/weather?city=%E5%8C%97%E4%BA%AC")
const res3 = axios.get("https://v2.api-m.com/api/music163hot")
// all是用于处理多个响应的
axios.all([res1,res2,res3]).then(res=>{
// console.log('成功获取数据!',res);
let [bzData,tqData,yyData] = res;
console.log(bzData.data)
console.log(tqData.data)
console.log(yyData.data)
}).catch(reason => {
console.log('失败!', reason);
});
}
</script>
拦截器
axios的也可以设置拦截器:拦截每次请求和响应
- axios.interceptors.request.use(请求成功拦截, 请求失败拦截)
- axios.interceptors.response.use(响应成功拦截, 响应失败拦截) 图示如下:
代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/nprogress/0.2.0/nprogress.min.js"></script>
<link href="https://cdn.bootcdn.net/ajax/libs/nprogress/0.2.0/nprogress.min.css" rel="stylesheet">
</head>
<body>
<button id="btn1">发送请求</button>
<script>
const btn1 = document.querySelector("#btn1");
// 请求拦截器 config是配置对象
axios.interceptors.request.use(config=>{
// 表示拦截后,给请求头上添加一个a
config.headers.a = 1;
NProgress.start(); // 显示进度条
// 放行
return config;
})
// 响应拦截器
axios.interceptors.response.use(response=>{
NProgress.done(); // 关闭进度条
return response;
},err=>{
// 失败的回调,直接响应失败的promsie
return Promise.reject(err)
})
btn1.onclick = async function () {
axios.get("http://localhost:3000/users").then(res=>{
console.log('成功获取数据!',res.data);
}).catch(reason => {
console.log('失败!', reason);
});
}
</script>
</body>
</html>