Vue学习笔记——前后端交互
目标:
- 能够说出什么是前后端交互模式
- 能够说出 Promise 的相关概念和用法
- 能够使用 fetch 进行接口调用
- 能够使用 axios 进行接口调用
- 能够使用 async/await 方式调用接口 (ES7)
- 能够基于后台接口实现案例
fetch API:是标准化组织专门提供的一种新型的调用后台的接口,比Ajax的API要强大很多
axios:第三方的库,专门用于事件接口的调用
1. 前后端交互模式
1.1 接口调用方式
- 原生Ajax
- 基于jQuery的ajax (用于DOM操作)
- fetch
- axios
1.2 URL地址格式
1. 传统形式的URL
格式:schema://host:port/path?query#fragment
- schema:协议。 例如:
- host:域名或者IP地址
- port:端口
- path:路径
- query:查询参数
- fragment:锚点(哈希),用于定位页面的某个位置
2. Restful 形式的URL
http://localhost:3000/index/123 (这里的传参方式不一样,直接斜杆)
2. Promise 用法
- 异步效果分析
① 定时任务
② Ajax
③ 事件函数 - 多次异步调用的依赖分析
- 多次异步调用的结果顺序不确定
- 异步调用结果如果存在依赖需要嵌套
Promise是一个构造函数,也是对象(方法也是)
- 实例化 Promise 对象,构造函数中传递函数,该函数用于处理异步任务
- resolve 和 reject 两个参数用于处理成功和失败两种情况,并通过 p.then 获取处理结果
var p = new Promise(function(resolve,reject){
//成功时调用 resolve()
//失败时调用reject()
});
p.then(function(ret){
//从resolve得到正常结果
},function(ret){
//从reject得到错误信息
});
2.1 基于Promise处理Ajax请求
1. 发送多次请求
function queryData(url){
// 1.创建一个promise实例
var p = new Promise(function(resolve,reject){
var xhr = new XMLHttpRequest();
//指定一个回调函数
xhr.onreadystatechange = function(){
if(xhr.readyState != 4) return;
if(xhr.readyState == 4 && xhr.status == 200){
// 2. 处理正常的情况
resolve(xhr.responseText);
}else{
// 3.处理异常的情况
reject('服务器错误');
}
};
xhr.open('get',url);
xhr.send(null); //为什么要传null
});
return p;
}
queryData('http://localhost:3000/data')
.then(function(data){
console.log(data);
// 想要继续链式编程下去 需要 return
return queryData('http://localhost:3000/data1');
})
.then(function(data){
return queryData('http://localhost:3000/data2');
})
.then(function(data){
console.log(data);
})
- 多个任务通过.then的方式,把他们变成线性关系(这样就保证了执行顺序)
- 返回的是一个新的Promise对象,下一个.then的调用者就是上边返回出来的对象
- data参数(你也可以去别的名字):用于接收上一个异步任务处理的结果
2.2 Promise常用API
1. 实例方法
- p.then( ) 得到异步任务的正确结果
- 返回Promise实例对象(返回的该实例对象会调用下一个then)
- 返回普通值(返回的普通值 会直接传递给下一个then,通过then 参数中函数的参数接收该值。返回普通值了那它是怎么调用的?会默认的产生一个实例对象让下一个调用)
- p.catch( ) 获取异常信息
- p.finally( ) 成功与否都会执行
2. 对象方法
- Promise.all( ) 并发处理多个异步任务,所有任务都执行完成才能得到结果(结果顺序与传参顺序一 一对应)
- Promise.race( ) 并发处理多个异步任务,只要有一个任务完成就能得到结果
var p1=queryData('http://localhost:3000/a1');
var p2=queryData('http://localhost:3000/a2');
var p3=queryData('http://localhost:3000/a3');
Promise.all([p1,p2,p3]).then(function(result){
console.log(result);
})
Promise.race([p1,p2,p3]).then(function(result){
console.log(result);
})
3. 接口调用— fetch 用法
3.1 概述
1. 基本特性
- 可看作是xhr的升级版
(fetch不是Ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象) - 基于Promise实现
- fetch 会返回Promise
2. 语法结构
(then两次)
fetch(url, options)
.then(fn1)
.then(fn2)
…
.catch(fn)
3.2 fetch的基本用法
<script>
fetch('http://localhost:3000/fdata').then(function(data){
//text()方法属于fetchAPI的一部分。它返回一个Promise实例对象,用于获取后台返回的数据
return data.text();
}).then(function(data){
// 在这个then里面我们能拿到最终的数据
console.log(data);
})
</script>
3.3 fetch API中的HTTP请求
1. 常用配置选项
- method(String): HTTP请求方法,默认GET(GET、POST、PUT、DELETE)
- body(String):HTTP的请求参数
- headers(Object):HTTP的请求头
在url后头添加一个对象,用来配置上面的信息
2. GET请求参数
(DELETE请求参数与此相似)
- 传统的URL传递参数
- restful形式的URL传递参数 通过 / 的形式传递参数
(后台的配置不一样)
/*
前端
*/
<script type="text/javascript">
fetch('http://localhost:3000/books/14253',{
method:'get'
})
.then(function(data){
//text()方法属于fetchAPI的一部分。它返回一个Promise实例对象,用于获取后台返回的数据
return data.text();
}).then(function(data){
// 在这个then里面我们能拿到最终的数据
console.log(data);
})
</script>
/*
后端
*/
app.get('/books/:id', (req, res) => {
res.send('Restful形式的URL传递参数!' + req.params.id)
})
使用req.params来获取参数
3. POST请求参数
(PUT请求参数与此相似)
- 字符串格式
- json格式
<script type="text/javascript">
//字符串格式
fetch('http://localhost:3000/books',{
method:'post',
body:'uname=xingxing&pwd=123',
headers:{
'Content-Type':'application/x-www-form-urlencoded',
}
}).then(data=>{
return data.text();
}).then(ret=>{
console.log(ret);
})
</script>
//json格式
fetch('http://localhost:3000/books', {
method: 'post',
body: JSON.stringify({
uname: '张三',
pwd: '456'
}),
headers: {
'Content-Type': 'application/json'
}
})
.then(function(data){
return data.text();
}).then(function(data){
console.log(data)
});
//后端
app.post('/books', (req, res) => {
res.send('post请求传递参数!' + req.body.uname+'======'+req.body.pwd)
})
app.put('/books/:id', (req, res) => {
res.send('put请求传递参数!' + req.body.uname+'======'+req.body.pwd)
})
json格式时,后端需要修改一下。(具体为什么还没有细究)好像是mytoken和content-type分开写会被覆盖
暂时是写入这个代码: res.header(‘Access-Control-Allow-Headers’, [‘mytoken’,‘Content-Type’]);
3.3 fetch响应结果
响应数据格式
- text():将返回体处理成字符串类型
- json():返回结果和JSON.parse(response Text)一样
(将json替换text)
fetch('http://localhost:3000/booksjson').then(function(data){
return data.json();
// return data.text();
}).then(function(data){
console.log(data)
// console.log(typeof data)
// var obj = JSON.parse(data);
// console.log(obj.uname,obj.age,obj.gender)
})
//后端:
app.get('/booksjson', (req, res) => {
res.json({
uname: 'lili',
age: 13,
gender: 'female'
});
})
就是:后端返回的是json数据类型
如果你用text()获取到的格式是字符串类型
如果你用json()拿到的就是json对象,
后端是字符串你就不需要使用到json了吧?!没必要哇
4. 接口调用— axios 用法
4.1 axios的基本特性
- 支持浏览器和node.js
- 支持promise
- 能拦截请求和响应
- 自动转换JSON数据
4.2 axios的基本用法
① 使用axios需要引入axios库文件文件
② 参考代码:
axios.get('http://localhost:3000/adata')
.then(function(ret){
//拿到的ret是一个对象, 后台响应的数据都存在ret的data属性里
//data属性名称是固定的,用于获取后台响应的数据
console.log(ret.data);
})
4.3 axios API中的HTTP请求
1. get 和 delete 请求传递参数
- 通过传统的 url 以 ?的形式传递参数
- restful 形式传递参数
- 通过params 形式传递参数 (★)
通过params选项传递:
axios.get(“http://localhost:3000/axios”,{
params:{
id:123
}
}).then(data=>{
console.log(data.data)
})
axios.get("http://localhost:3000/axios?id=123")
.then(data=>{
console.log(data);
})
axios.get("http://localhost:3000/axios/123")
.then(data=>{
console.log(data.data);
})
axios.get("http://localhost:3000/axios",{
params:{
id:123
}
}).then(data=>{
console.log(data.data)
})
//后端
//传统的url形式与params形式 获取参数都是用req.query的方式
app.get('/axios',(req,res)=>{
res.send('axios 传统方式获取到的数据'+req.query.id);
})
app.get('/axios/:id',(req,res)=>{
res.send('axios resful方式获取到的数据'+req.params.id);
})
2. post 和 put 请求传递参数
- 通过选项传递参数 (默认传递的是json格式的数据)
在url后头加一个参数:json对象 - 通过URLSearchParams 传递参数 ( application/x-www-form-urlencoded 表单形式的数据 )
不知道为什么,URLSearchParams 传递参数 后台拿不到数据,但前端是传递过去了的!!!?
//是对象哦
axios.post("http://localhost:3000/axios",{
uname:'jerry',
pwd:456
}).then(data=>{
console.log(data.data)
})
//方式二:
const params = new URLSearchParams();
//键值对
params.append('uname','zhangsan');
params.append('pwd','111');
axios.post("http://localhost:3000/axios",params).then(data=>{
console.log(data.data)
})
//后端:
app.post('/axios', (req, res) => {
res.send('axios post 传递参数' + req.query.uname + '---' + req.body.pwd)
})
4.3 axios 的响应结果
(后台响应对应的结果)
对于JSON格式不需要自己再做转化了,直接就可以拿来用。像这样:
axios.get(''
4.4 axios 的全局配置
- 配置 超时时间
axios.defaults.timeout = 3000; //超时时间 - 配置 请求的基准URL地址
axios.defaults.baseURL = 'http://localhost:3000/app; //默认地址
-配置 请求头
axios.defaults.headers[‘mytoken’] = ‘一串自定义文字’ //设置请求头 - 配置公共的 post 的 Content-Type
axios.defaults.headers.post[‘Content-Type’] = ‘application/x-www-form-urlencoded’;
4.4 axios 拦截器
1. 请求拦截器
在请求发出去之前设置一些信息
//添加一个请求拦截器
axios.interceptors.request.use(function(config){
//在请求发出之前进行一些信息设置
console.log(config.url);
config.headers.mytoken = 'nihao';
return config;
},function(err){
//处理响应的错误信息
console.log(err);
});
axios.get('http://localhost:3000/adata').then(function(data){
console.log(data);
})
在config中进行设置(config相当于是个对象)
2. 响应拦截器
在获取数据之前对数据做一些加工处理
axios.interceptors.response.use(function(res){
//在请求发出之前进行一些信息设置
//直接在响应拦截器中获取到我们需要的数据。在发送请求调用接口的时候在then当中就可以拿到实际的数据,不再需要通过.data的方式
console.log(res);
var data = res.data;
return data;
},function(err){
//处理响应的错误信息
console.log(err);
});
形参表示后台返回的数据信息,对象中的data
res并不是实际的数据,是axios所包含的对象,通过对象中的data拿到实际的数据(和获取后台数据是一样的)
5. 接口调用— async/await用法
- async 关键字用于函数上 (async函数的返回值是Promise实例对象) 还是可以使用then方法
- await 关键字用于 async函数当中(await可以得到异步的结果)
不要.then了,因为加上await后可以直接获取到异步任务的结果
参考案例:
async function queryData(){
var ret = await new Promise(function(resolve,reject){
setTimeout(function(){
resolve('nihao');
},1000);
})
return ret;
}
queryData().then(result=>{
console.log(result);
});
处理多个异步请求
async function queryData(){
var info = await axios.get('async1');
var ret = await axios.get('async2/?info='+info.data);
return ret.data;
}
//要记得调用一下哇
queryData().then(function(data){
console.log(data);
})