记录:263
体验XMLHttpRequest、jquery、Promise、fetch、axios的异步方式调用后端接口。
本例环境:
后端:node.js、express。
前端:Vue.js、HTML、CSS、jQuery、axios。
方式:分别使用XMLHttpRequest、jquery、Promise、fetch、axios的异步方式调用后端接口。
Ajax:Asynchronous Javascript And XML(异步JavaScript和XML)。在网页中利用 XMLHttpRequest对象和服务器进行数据交互的方式。
本例目录结构:
vue_demo02\server目录:存放后端相关代码。
vue_demo02\front目录:存放前端相关代码
名词:
express:web application framework for node.是一个简洁而灵活的node.js Web应用框架, 提供一系列强大特性帮助你创建各种Web应用
Nodemon:Nodemon is a utility, that will monitor for any changes in your source and automatically restart your server.一款非常实用的工具,用来监控 node.js 源代码的任何变化和自动重启服务器。
DOM:文档对象模型(Document Object Model)。
1.体验基于node.js搭建简单服务器
vue_demo02\server目录中。
index.js:服务入口文件,使用nodemon命令启动即可;
vue_demo02\server\node_modules目录:存放安装依赖模块;
vue_demo02\server\public目录:存放静态文件。
1.1初始化vue_demo02/server
使用VS Code编辑器打开vue_demo02
1.1.1 点击菜单Terminal->New Terminal开一个命令行Terminal窗口
1.1.2 进入vue_demo02\server目录
1.1.3 安装express模块
执行指令:npm install express
1.1.3 安装nodemon模块
执行指令:npm install -g nodemon
1.2在vue_demo02/server/index.js初始化服务器
代码如下:
//1.导入模块
const express = require('express');
const app = express();
//2.配置服务器
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
app.all('*', function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Headers', 'Content-Type');
res.header('Content-Type', 'application/json;charset=utf-8')
next();
});
//3.发布服务
app.get('/getInfo',(req,res)=>{
console.log('接收到浏览器请求.');
var girInfo='身高:160;体重:100;罩杯:C';
res.send(girInfo);
});
app.get('/getGirlInfo', (req, res) => {
var girlInfo = {
id: 1,
name: 'ZhangHz',
height: '161',
weight: '51',
cup: 'B'
};
if (req.query.name != 'ZhangHz') {
girlInfo='请核对后,再查询.';
};
res.send(girlInfo);
});
app.post('/getGirlInfoPost', (req, res) => {
var girlInfo = {
id: 1,
name: 'ZhangBj',
height: '162',
weight: '52',
cup: 'C'
};
if (req.body.name != 'ZhangBj') {
girlInfo='请核对后,再查询.';
};
res.send(girlInfo);
});
//4.启动服务器
app.listen(8082, () => {
console.log('express服务器启动成功.');
console.log('监听端口: 8082')
});
1.3在控制台启动服务器
打开cmd.exe控制台进入vue_demo02\server目录
执行指令:nodemon index.js
启动日志:
1.4在浏览器发起请求
请求地址:http://127.0.0.1:8082/getInfo
1.4.1服务器端日志
接收到浏览器请求
1.4.2浏览器返回值
浏览器返回请求信息:
2.体验XMLHttpRequest
XMLHttpRequest对象提供了对 HTTP 协议的完全的访问,包括做出POST和HEAD请求以及GET请求。可以同步或异步地返回Web服务器的响应,能够以文本或者一个 DOM 文档的形式返回内容。
主流js的前后端交互框架均封装了的XMLHttpRequest对象。
在jQuery.js中:
jQuery.ajaxSettings.xhr = function() {
try {
return new window.XMLHttpRequest();
} catch ( e ) {}
};
在axios.js中
var request = new XMLHttpRequest();
2.1HTML标签
<div id="app">
<div class="grid">
<div><strong>体验前后端交互-XMLHttpRequest</strong></div>
<div class="titlePad" style="color: blue;">1.XMLHttpRequest的GET请求</div>
<div class="buttonPad"><button @click='getGirlInfo'>点击</button></div>
<div>
<table>
<thead>
<tr>
<th>姓名</th>
<th>身高</th>
<th>体重</th>
<th>罩杯</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{girlInfo.name}}</td>
<td>{{girlInfo.height}}</td>
<td>{{girlInfo.weight }}</td>
<td>{{girlInfo.cup }}</td>
</tr>
</tbody>
</table>
</div>
<div class="titlePad" style="color: blue;">2.XMLHttpRequest的POST请求</div>
<div class="buttonPad"><button @click='getGirlInfoPost'>点击</button></div>
<div>
<table>
<thead>
<tr>
<th>姓名</th>
<th>身高</th>
<th>体重</th>
<th>罩杯</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{girlInfoPost.name}}</td>
<td>{{girlInfoPost.height}}</td>
<td>{{girlInfoPost.weight }}</td>
<td>{{girlInfoPost.cup }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
2.2css代码
<style type="text/css">
.grid {
margin: auto;
width: 520px;
text-align: center;
}
.grid table {
border-top: 1px solid #f7b62a;
width: 100%;
border-collapse: collapse;
}
.grid th,
td {
padding: 10;
border: 1px solid #f7b62a;
height: 35px;
line-height: 35px;
}
.grid th {
background-color: #f7b62a;
}
.titlePad {
margin-top: 5px;
margin-bottom: 5px;
}
.buttonPad {
margin-bottom: 5px;
}
</style>
2.3js代码
//异步GET请求
function getGirlInfoByGet(vueThisObj) {
var vueThis = vueThisObj;
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://127.0.0.1:8082/getGirlInfo?name=ZhangHz");
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
vueThis.girlInfo = JSON.parse(xhr.responseText);
} else {
}
};
}
//异步POST请求
function getGirlInfoByPost(vueThisObj) {
var vueThis = vueThisObj;
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://127.0.0.1:8082/getGirlInfoPost");
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
xhr.send("name=ZhangBj&height=162");
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
vueThis.girlInfoPost = JSON.parse(xhr.responseText);
} else {
}
};
}
2.4对应Vue代码
var vm = new Vue({
el: '#app',
data: {
girlInfo: {},
girlInfoPost: {},
},
methods: {
getGirlInfo: function () {
getGirlInfoByGet(this);
},
getGirlInfoPost: function () {
getGirlInfoByPost(this);
}
}
});
注意:
在Vue的vm实例的getGirlInfo函数中,将this对象传入给getGirlInfoByGet,作用是给getGirlInfoByGet的onreadystatechange对应回调函数使用。
原因:onreadystatechange对应回调函数的this是指向getGirlInfoByGet而不是指向Vue的vm实例。
2.5后端代码
app.get('/getGirlInfo', (req, res) => {
var girlInfo = {
id: 1,
name: 'ZhangHz',
height: '161',
weight: '51',
cup: 'B'
};
if (req.query.name != 'ZhangHz') {
girlInfo='请核对后,再查询.';
};
res.send(girlInfo);
});
app.post('/getGirlInfoPost', (req, res) => {
var girlInfo = {
id: 1,
name: 'ZhangBj',
height: '162',
weight: '52',
cup: 'C'
};
if (req.body.name != 'ZhangBj') {
girlInfo='请核对后,再查询.';
};
res.send(girlInfo);
});
2.6效果
运行效果如下:
3.体验jquery的ajax
jquery的ajax执行AJAX(异步 HTTP)请求。
3.1HTML标签
<div id="app">
<div class="grid">
<div><strong>体验前后端交互-jquery的ajax</strong></div>
<div class="titlePad" style="color: blue;">1. jquery的ajax的GET请求</div>
<div class="buttonPad"><button @click='getGirlInfo'>点击</button></div>
<div>
<table>
<thead>
<tr>
<th>姓名</th>
<th>身高</th>
<th>体重</th>
<th>罩杯</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{girlInfo.name}}</td>
<td>{{girlInfo.height}}</td>
<td>{{girlInfo.weight }}</td>
<td>{{girlInfo.cup }}</td>
</tr>
</tbody>
</table>
</div>
<div class="titlePad" style="color: blue;">2.jquery的ajax的POST请求</div>
<div class="buttonPad"><button @click='getGirlInfoPost'>点击</button></div>
<div>
<table>
<thead>
<tr>
<th>姓名</th>
<th>身高</th>
<th>体重</th>
<th>罩杯</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{girlInfoPost.name}}</td>
<td>{{girlInfoPost.height}}</td>
<td>{{girlInfoPost.weight }}</td>
<td>{{girlInfoPost.cup }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
3.2css代码
<style type="text/css">
.grid {
margin: auto;
width: 520px;
text-align: center;
}
.grid table {
border-top: 1px solid #f7b62a;
width: 100%;
border-collapse: collapse;
}
.grid th,
td {
padding: 10;
border: 1px solid #f7b62a;
height: 35px;
line-height: 35px;
}
.grid th {
background-color: #f7b62a;
}
.titlePad {
margin-top: 5px;
margin-bottom: 5px;
}
.buttonPad {
margin-bottom: 5px;
}
</style>
3.3js代码
//异步GET请求
function getGirlInfoByGet(vueThisObj) {
var vueThis = vueThisObj;
$.ajax({
type: 'GET',
url: 'http://127.0.0.1:8082/getGirlInfo',
data: {
name: 'ZhangHz'
},
success: function (result) {
vueThis.girlInfo = result;
}
});
}
//异步POST请求
function getGirlInfoByPost(vueThisObj) {
var vueThis = vueThisObj;
$.ajax({
type: 'POST',
url: 'http://127.0.0.1:8082/getGirlInfoPost',
data: {
name: 'ZhangBj',
height: 162
},
success: function (result) {
vueThis.girlInfoPost = result;
}
});
}
3.4对应Vue代码
var vm = new Vue({
el: '#app',
data: {
girlInfo: {},
girlInfoPost: {},
},
methods: {
getGirlInfo: function () {
getGirlInfoByGet(this);
},
getGirlInfoPost: function () {
getGirlInfoByPost(this);
}
}
});
3.5后端代码
app.get('/getGirlInfo', (req, res) => {
var girlInfo = {
id: 1,
name: 'ZhangHz',
height: '161',
weight: '51',
cup: 'B'
};
if (req.query.name != 'ZhangHz') {
girlInfo='请核对后,再查询.';
};
res.send(girlInfo);
});
app.post('/getGirlInfoPost', (req, res) => {
var girlInfo = {
id: 1,
name: 'ZhangBj',
height: '162',
weight: '52',
cup: 'C'
};
if (req.body.name != 'ZhangBj') {
girlInfo='请核对后,再查询.';
};
res.send(girlInfo);
});
3.6效果
运行效果如下:
4.体验Promise
Promise 对象用于表示一个异步操作的最终完成 (或失败)及其结果值。
4.1HTML标签
<div id="app">
<div class="grid">
<div><strong>体验前后端交互-Promise</strong></div>
<div class="titlePad" style="color: blue;">1. Promise的GET请求</div>
<div class="buttonPad"><button @click='getGirlInfo'>点击</button></div>
<div>
<table>
<thead>
<tr>
<th>姓名</th>
<th>身高</th>
<th>体重</th>
<th>罩杯</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{girlInfo.name}}</td>
<td>{{girlInfo.height}}</td>
<td>{{girlInfo.weight }}</td>
<td>{{girlInfo.cup }}</td>
</tr>
</tbody>
</table>
</div>
<div class="titlePad" style="color: blue;">2.Promise的POST请求</div>
<div class="buttonPad"><button @click='getGirlInfoPost'>点击</button></div>
<div>
<table>
<thead>
<tr>
<th>姓名</th>
<th>身高</th>
<th>体重</th>
<th>罩杯</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{girlInfoPost.name}}</td>
<td>{{girlInfoPost.height}}</td>
<td>{{girlInfoPost.weight }}</td>
<td>{{girlInfoPost.cup }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
4.2css代码
<style type="text/css">
.grid {
margin: auto;
width: 520px;
text-align: center;
}
.grid table {
border-top: 1px solid #f7b62a;
width: 100%;
border-collapse: collapse;
}
.grid th,
td {
padding: 10;
border: 1px solid #f7b62a;
height: 35px;
line-height: 35px;
}
.grid th {
background-color: #f7b62a;
}
.titlePad {
margin-top: 5px;
margin-bottom: 5px;
}
.buttonPad {
margin-bottom: 5px;
}
</style>
4.3js代码
//异步GET请求
function getGirlInfoByGet() {
var promise = new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://127.0.0.1:8082/getGirlInfo?name=ZhangHz");
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
resolve(xhr.responseText);
} else {
}
};
});
return promise;
}
//异步POST请求
function getGirlInfoByPost() {
var promise = new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://127.0.0.1:8082/getGirlInfoPost");
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
xhr.send("name=ZhangBj&height=162");
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
resolve(xhr.responseText);
} else {
}
};
});
return promise;
}
4.4对应Vue代码
var vm = new Vue({
el: '#app',
data: {
girlInfo: {},
girlInfoPost: {},
},
methods: {
getGirlInfo: function () {
var vueThis = this;
getGirlInfoByGet().then(function (data) {
vueThis.girlInfo = JSON.parse(data);
}, function (info) {
console.log("服务异常.");
});
},
getGirlInfoPost: function () {
var vueThis = this;
getGirlInfoByPost().then(function (data) {
vueThis.girlInfoPost = JSON.parse(data);
}, function (info) {
console.log("服务异常.");
});
}
}
});
4.5后端代码
app.get('/getGirlInfo', (req, res) => {
var girlInfo = {
id: 1,
name: 'ZhangHz',
height: '161',
weight: '51',
cup: 'B'
};
if (req.query.name != 'ZhangHz') {
girlInfo='请核对后,再查询.';
};
res.send(girlInfo);
});
app.post('/getGirlInfoPost', (req, res) => {
var girlInfo = {
id: 1,
name: 'ZhangBj',
height: '162',
weight: '52',
cup: 'C'
};
if (req.body.name != 'ZhangBj') {
girlInfo='请核对后,再查询.';
};
res.send(girlInfo);
});
4.6效果
运行效果如下:
5.体验fetch
Fetch API提供了一个JavaScript接口,用于访问和操纵HTTP管道的请求和响应等。
5.1HTML标签
<div id="app">
<div class="grid">
<div><strong>体验前后端交互-fetch</strong></div>
<div class="titlePad" style="color: blue;">1.fetch的GET请求</div>
<div class="buttonPad"><button @click='getGirlInfo'>点击</button></div>
<div>
<table>
<thead>
<tr>
<th>姓名</th>
<th>身高</th>
<th>体重</th>
<th>罩杯</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{girlInfo.name}}</td>
<td>{{girlInfo.height}}</td>
<td>{{girlInfo.weight }}</td>
<td>{{girlInfo.cup }}</td>
</tr>
</tbody>
</table>
</div>
<div class="titlePad" style="color: blue;">2.fetch的POST请求</div>
<div class="buttonPad"><button @click='getGirlInfoPost'>点击</button></div>
<div>
<table>
<thead>
<tr>
<th>姓名</th>
<th>身高</th>
<th>体重</th>
<th>罩杯</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{girlInfoPost.name}}</td>
<td>{{girlInfoPost.height}}</td>
<td>{{girlInfoPost.weight }}</td>
<td>{{girlInfoPost.cup }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
5.2css代码
<style type="text/css">
.grid {
margin: auto;
width: 520px;
text-align: center;
}
.grid table {
border-top: 1px solid #f7b62a;
width: 100%;
border-collapse: collapse;
}
.grid th,
td {
padding: 10;
border: 1px solid #f7b62a;
height: 35px;
line-height: 35px;
}
.grid th {
background-color: #f7b62a;
}
.titlePad {
margin-top: 5px;
margin-bottom: 5px;
}
.buttonPad {
margin-bottom: 5px;
}
</style>
5.3js代码
//异步GET请求
function getGirlInfoByGet(vueThisObj) {
var vueThis = vueThisObj;
fetch('http://127.0.0.1:8082/getGirlInfo?name=ZhangHz', {
method: 'get'
}).then(function (data) {
return data.text();
}).then(function (data) {
vueThis.girlInfo = JSON.parse(data);
});
}
异步POST请求
function getGirlInfoByPost(vueThisObj) {
var vueThis = vueThisObj;
fetch('http://127.0.0.1:8082/getGirlInfoPost', {
method: 'POST',
body: JSON.stringify({
name: 'ZhangBj',
height: '162'
}),
headers: {
'Content-Type': 'application/json'
}
}).then(function (data) {
return data.text();
}).then(function (data) {
vueThis.girlInfoPost = JSON.parse(data);
});
}
5.4对应Vue代码
var vm = new Vue({
el: '#app',
data: {
girlInfo: {},
girlInfoPost: {},
},
methods: {
getGirlInfo: function () {
getGirlInfoByGet(this);
},
getGirlInfoPost: function () {
getGirlInfoByPost(this);
}
}
});
5.5后端代码
app.get('/getGirlInfo', (req, res) => {
var girlInfo = {
id: 1,
name: 'ZhangHz',
height: '161',
weight: '51',
cup: 'B'
};
if (req.query.name != 'ZhangHz') {
girlInfo='请核对后,再查询.';
};
res.send(girlInfo);
});
app.post('/getGirlInfoPost', (req, res) => {
var girlInfo = {
id: 1,
name: 'ZhangBj',
height: '162',
weight: '52',
cup: 'C'
};
if (req.body.name != 'ZhangBj') {
girlInfo='请核对后,再查询.';
};
res.send(girlInfo);
});
5.6效果
运行效果如下:
6.体验axios
axios是一个易用、简洁且高效的http库。
6.1HTML标签
<div id="app">
<div class="grid">
<div><strong>体验前后端交互-axios</strong></div>
<div class="titlePad" style="color: blue;">1.axios的GET请求</div>
<div class="buttonPad"><button @click='getGirlInfo'>点击</button></div>
<div>
<table>
<thead>
<tr>
<th>姓名</th>
<th>身高</th>
<th>体重</th>
<th>罩杯</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{girlInfo.name}}</td>
<td>{{girlInfo.height}}</td>
<td>{{girlInfo.weight }}</td>
<td>{{girlInfo.cup }}</td>
</tr>
</tbody>
</table>
</div>
<div class="titlePad" style="color: blue;">2.axios的POST请求</div>
<div class="buttonPad"><button @click='getGirlInfoPost'>点击</button></div>
<div>
<table>
<thead>
<tr>
<th>姓名</th>
<th>身高</th>
<th>体重</th>
<th>罩杯</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{girlInfoPost.name}}</td>
<td>{{girlInfoPost.height}}</td>
<td>{{girlInfoPost.weight }}</td>
<td>{{girlInfoPost.cup }}</td>
</tr>
</tbody>
</table>
</div>
<div class="titlePad" style="color: blue;">3.axios的GET请求-async和await关键字</div>
<div class="buttonPad"><button @click='getGirlInfoV1'>点击</button></div>
<div>
<table>
<thead>
<tr>
<th>姓名</th>
<th>身高</th>
<th>体重</th>
<th>罩杯</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{girlInfoV1.name}}</td>
<td>{{girlInfoV1.height}}</td>
<td>{{girlInfoV1.weight }}</td>
<td>{{girlInfoV1.cup }}</td>
</tr>
</tbody>
</table>
</div>
<div class="titlePad" style="color: blue;">4.axios的POST请求-async和await关键字</div>
<div class="buttonPad"><button @click='getGirlInfoPostV1'>点击</button></div>
<div>
<table>
<thead>
<tr>
<th>姓名</th>
<th>身高</th>
<th>体重</th>
<th>罩杯</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{girlInfoPostV1.name}}</td>
<td>{{girlInfoPostV1.height}}</td>
<td>{{girlInfoPostV1.weight }}</td>
<td>{{girlInfoPostV1.cup }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
6.2css代码
<style type="text/css">
.grid {
margin: auto;
width: 520px;
text-align: center;
}
.grid table {
border-top: 1px solid #f7b62a;
width: 100%;
border-collapse: collapse;
}
.grid th,
td {
padding: 10;
border: 1px solid #f7b62a;
height: 35px;
line-height: 35px;
}
.grid th {
background-color: #f7b62a;
}
.titlePad {
margin-top: 5px;
margin-bottom: 5px;
}
.buttonPad {
margin-bottom: 5px;
}
</style>
6.3js代码
//异步GET请求
function getGirlInfoByGet(vueThisObj) {
var vueThis = vueThisObj;
axios.get('http://127.0.0.1:8082/getGirlInfo', {
params: {
name: 'ZhangHz'
}
}).then(function (result) {
vueThis.girlInfo = result.data;
})
}
异步POST请求
function getGirlInfoByPost(vueThisObj) {
var vueThis = vueThisObj;
axios.post('http://127.0.0.1:8082/getGirlInfoPost', {
name: 'ZhangBj',
height: 162
}).then(function (result) {
vueThis.girlInfoPost = result.data;
});
}
6.4对应Vue代码
var vm = new Vue({
el: '#app',
data: {
girlInfo: {},
girlInfoPost: {},
girlInfoV1: {},
girlInfoPostV1: {},
},
methods: {
getGirlInfo: function () {
getGirlInfoByGet(this);
},
getGirlInfoPost: function () {
getGirlInfoByPost(this);
},
getGirlInfoV1: async function () {
axios.defaults.baseURL = 'http://127.0.0.1:8082/';
var ret = await axios.get('getGirlInfo?name=ZhangHz');
this.girlInfoV1 = ret.data;
},
getGirlInfoPostV1: async function () {
axios.defaults.baseURL = 'http://127.0.0.1:8082/';
var ret = await axios.post('getGirlInfoPost', {
name: 'ZhangBj',
height: 162
});
this.girlInfoPostV1 = ret.data;
}
}
});
6.5后端代码
app.get('/getGirlInfo', (req, res) => {
var girlInfo = {
id: 1,
name: 'ZhangHz',
height: '161',
weight: '51',
cup: 'B'
};
if (req.query.name != 'ZhangHz') {
girlInfo='请核对后,再查询.';
};
res.send(girlInfo);
});
app.post('/getGirlInfoPost', (req, res) => {
var girlInfo = {
id: 1,
name: 'ZhangBj',
height: '162',
weight: '52',
cup: 'C'
};
if (req.body.name != 'ZhangBj') {
girlInfo='请核对后,再查询.';
};
res.send(girlInfo);
});
6.6效果
运行效果如下:
以上,感谢。
2021年9月28日