一、前后端交互模式
1、接口调用方式
- 原生ajax
- 基于jQuery的ajax
- fetch
- axios
2、传统形式的URL
格式:schema://host:port/path?query#fragment
- schema:协议。例如http、https、ftp等
- host:域名或者IP地址
- port:端口。http默认端口80,可省略
- path:路径
- query:查询参数
- fragment:锚点(哈希Hash),用于定位页面的某个位置‘
3、Restful形式的URL
HTTP请求方式
| 名称 | 对应功能 |
|---|---|
| get | 查询 |
| post | 添加 |
| put | 修改 |
| delete | 删除 |
二、Promise使用
1、异步调用
- JavaScript层面的异步效果:
- 定时任务
- ajax
- 时间函数
- 多次异步调用的依赖分析
- 多次异步调用的结果顺序不确定
- 异步调用结果如果存在以来需要嵌套
一个简单的ajax异步代码如下:
$.ajax({
// url就是后端接口调用地址
url: 'XXXX',
success: function(data) {
console.log(data)
}
})
2、Promise概述
Promis是异步编程的一种解决方案,从语法上讲,Promis是一个对象,从他可以获取异步操作的消息。
使用Promise主要有以下好处:
- 可以避免多层异步调用嵌套问题(回调地狱)
- Promise对象提供了简介的API,使得控制异步操作更加容易
3、Promise基本用法
- 实例化Promise对象,构造函数中传递函数,该函数中用于处理异步任务
resolve和reject两个参数用于处理成功和失败两种情况,通过.them获取处理结果
var p = new Promise(function(resolve, reject) {
resolve('正常运行'); // 成功时调用resolve()
reject('出现错误'); // 失败时调用reject()
});
p.then(function(data) {
console.log(data); // 从resolve得到正常结果
}, function(info) {
console.log(info); // 从reject得到错误信息
});
4、基于Promise发送ajax请求
直接上代码:
function queryData(url) { // url是api接口地址
var p = new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
// 回调函数
xhr.onreadystatechange = function() {
// 只要readystate一发生变化就会调用这个函数,所以这个函数不止调用了一次
if(xhr.readystate != 4) return;
if(xhr.readystate == 4 && xhr.status == 200) {
// 处理正常的情况
resolve(xhr.responseTest);
} else {
// 处理异常情况
reject('服务器错误');
}
}
xhr.open('get', url);
xhr.send(null);
});
return p;
}
// 使用上述函数
queryData('http://localhost....')
.then(function(data) {
console.log(data);
}, function(info) {
console.log(info);
});
可以通过多次调用.then 进行多次ajax异步请求
5、then参数中的函数返回值
- 返回Promise实例对象
- 返回的该实例对象会调用下一个then
- 返回普通值
- 返回的普通值会直接传递给下一个then,通过then参数中函数的参数接受该值
6、Promise中常用的api
(1)实例方法
- p.then() 得到异步任务的正确结果
- p.catch() 获取异常信息
- p.finally() 成功与否都会执行(尚且不是正式标准)
queryData()
.then(function(data) {
console.log(data);
})
.catch(function(data) {
console.log(data);
})
.finally(function() {
console.log('finished')
});
(2)对象方法
- Promise.all() 并发的处理多个异步任务,所有任务都执行完成才能得到结果
- Promise.race() 并发的处理多个异步任务,只要有一个任务完成就能得到结果
// queryData()函数是上述自己编写的
var p1 = queryData(url1);
var p2 = queryData(url2);
var p3 = queryData(url3);
// all()
Promise.all([p1, p2, p3]).then(function(result) {
console.log(result);
});
// race()
Promise.race([p1, p2, p3]).then(function(result) {
console.log(result);
});
三、接口调用——fetch用法
1、基本特性
- 更加简单的数据获取方式,功能更加强大、更灵活,可以看作是xhr的升级版
- 基于Promise实现
2、语法结构
fecth(url).then(fun1)
.then(fun2)
....
.then(fn)
注意 text() 方法,由于fetch返回的是Promise,调用了text() 之后才是真正要获得的数据
fetch('/abc').then(data => {
return data.text();
}).then(ret => {
// 注意,这里得到的才是最终的数据
console.log(ret);
});
3、fetch请求参数
常用配置选项
method(String)HTTP请求方法,默认为GETbody(String)HTTP的请求参数headers(Object)HTTP的请求头,默认为 {}
(1)get请求方法的传参
// url中直接传参(传统、Restful)
fetch('/abc?id=123&pwd=abcd', { // 也可以写成 '/abc/123/abcd',后端代码会有所不同
method: 'get'
}).then(data => {
return data.text();
}).then(ret => {
// 注意,这里得到的才是最终的数据
console.log(ret);
});
(2)delete请求方法的传参
改变一下 mehtod: 'delete' 其他和get几乎一样
(3)post请求方法的传参
fetch('/books', {
method: 'post',
// body中传参数
body: 'username = list & pwd = 123',
// headers基本是固定的
headers: {
'Contene-Type':'application/x-www-form-urlencoded'
}
}).then(data => {
return data.text();
}).then(ret => {
// 注意,这里得到的才是最终的数据
console.log(ret);
});
针对post的body传参,还可以使用json函数进行优化
body: JSON.stringify({
username: 'list',
pwd: '123'
})
(4)put请求方法的传参
和post几乎一样
put请求主要用于修改数据,所以url中需要传入id,body中存放修改的参数
fetch('/books/{id}', {
method: 'put',
// body中传参数
body: JSON.stringify({
username: 'list',
pwd: '123'
}),
headers: {
'Contene-Type':'application/x-www-form-urlencoded'
}
}).then(data => {
return data.text();
}).then(ret => {
// 注意,这里得到的才是最终的数据
console.log(ret);
});
4、fetch响应结果
接收json字符串,代码:
fetch('/json').then(function(data) {
return data.json();
}).then(function(data) {
console.log(data);
});
四、接口调用——axios用法
第三方json库
专门实现接口调用,比fetch更加强大
1、axios的基本特征
axios是一个基于Promise用于浏览器和node.js的HTTP客户端。
具有以下特征:
- 支持浏览器和node.js
- 支持Promise
- 能拦截请求和相应
- 自动转换JSON数据
2、axios基本用法
axios.get('/data')
.then(ret => {
// data属性名称是固定的,用于获取后台相应的数据
console.log(ret.data)
})
3、axios的参数传递
(1)get参数传递
-
通过URL传递参数
axios.get('/data?id=123') .then(ret => { // data属性名称是固定的,用于获取后台相应的数据 console.log(ret.data) })axios.get('/data/123') .then(ret => { // data属性名称是固定的,用于获取后台相应的数据 console.log(ret.data) }) -
通过params选项传递参数
axios.get('/data', { params: { id: 123 } }) .then(ret => { // data属性名称是固定的,用于获取后台相应的数据 console.log(ret.data) })
(2)delete参数传递
和get一模一样,把get换成delete就好了
(3)post参数传递
-
通过选项传递参数(默认传递的是json格式的数据)
axios.post('/data', { username: 'admin', pwd: 123 }) .then(ret => { // data属性名称是固定的,用于获取后台相应的数据 console.log(ret.data) }) -
通过URLSearchParams传递参数(aaplication/x-www-form-urlencoded)
const params = new URLSearchParams(); params.append('username', 'admin'); params.append('pwd', 123); axios.post('/data', params).then(ret => { console.log(ret); });
(4)put参数传递
-
和post类似
axios.put('/data', { username: 'admin', pwd: 123 }) .then(ret => { // data属性名称是固定的,用于获取后台相应的数据 console.log(ret.data) })
4、axios的响应结果
响应结果的主要属性
- data:实际响应回来的数据
- headers:响应头信息
- status:响应状态码
- statusText:响应状态信息
axios.post('/data').then(ret => {
console.log(ret.data.{键值对的键名获取数据});
});
5、axios的全局配置
axios.default.timeout = 1000;超时时间axios.default.baseURL = 'http://local....'默认地址,最常用axios.default.headers['mytoken'] = 'XXXXXXX...'设置请求头
6、axios拦截器
-
请求拦截器:在发出请求之前设置一些信息
axios.interceptors.request.use(function(config) { // 操作,如:信息设置 return config; // return之后,请求继续发送,不return,程序卡在这运行不下去 }, function(err) { // 处理响应的错误信息 }); -
响应拦截器:在获取数据之前对数据做一些加工处理
axios.interceptors.response.use(function(res) { // 操作,如:信息设置 return res; // return之后,请求继续发送,不return,程序卡在这运行不下去 }, function(err) { // 处理响应的错误信息 });ps:这里的
res是一个对象,真正的数据存储在res.data中
五、接口调用——async/await用法
基本使用用法:
- ES7中引入的新语法,可以更方便的进行异步操作
async关键字用于函数上(async函数的返回值是Promise的实例对象)await关键字用于async函数当中(await可以得到异步的结果)
async function queryData(id) {
const ret = await axios.get('/data');
return ret;
}
queryData.then(ret => {
console.log(ret);
})
处理多个异步请求
async function queryData(id) {
const info = await axios.get('/data1');
const ret = await axios.get('/data2?info=' + info.data);
return ret;
}
queryData.then(ret => {
console.log(ret);
})