一、前言
在没有接触React、Angular、Vue这类MVVM的前端框架之前,无法抛弃Jquery的重要理由,除了优秀的前端DOM元素操作性以外,能够非常便捷的发起http请求也占有非常重要的地位。
既然我们已经开始使用Vue进行前端开发,抛弃了对页面DOM元素的操作,难道,为了方便的发起http请求,还需要在项目中加载jquery或者是手动创建http请求吗?
答案当然是不用的,作为目前主流的前端框架,开发者、社区早已经为我们提供好了解决方案。随着Vue作者尤雨溪宣布不再维护vue-resource,转而推荐大家使用axios,目前在Vue社区中axios开始占据http库的主导地位,所以这一章我们就介绍下如何使用axios发起http请求。
学习系列目录地址:https://www.cnblogs.com/danvic712/p/9549100.html
仓储地址(前端):https://github.com/Lanesra712/VueTrial/blob/master/chapter02-bronze/front/axios.html
仓储地址(后端):https://github.com/Lanesra712/VueTrial/tree/master/chapter02-bronze/rear/Sample
二、干货合集
axios是一个基于Promise的http客户端,可以用于浏览器和node.js。官方文档对于axios库的使用方法已经写的很清楚了,所以这里只介绍如何与Vue进行结合,从而使用axios发起http请求。
这一章会涉及到简单的前后端的数据交互,作为一名.NETer,本篇文章将采用ASP.NETCoreWebAPI作为后端服务,你可以根据自己的喜好进行选择。当然,如果你之前并没有接触过后端,不知道怎么选择的话,推荐你尝试.NETCore,示例的后端项目我也会同步放在Github上。
PS:在后端模板项目上,我会添加对于SwaggerAPI文档的支持,以及在后端程序中进行配置跨域请求,从而允许后端接口可以接受跨域请求的访问。这些内容并不会在本篇文章中展现,如果你需要详细了解,你可以查看另一个系列的文章(ASP.NETCore项目实战)那里会介绍一些关于ASP.NETCore项目的开发,两个系列相辅相成,后续所有涉及到前后端的交互开发,全部在此系列(ASP.NETCore项目实战)中进行呈现。
1、加载
同目前的前端发展方向相同,axios可以从npm、yarn、bower这种前端包管理工具中进行下载,同时,也提供了cdn链接,方便我们在传统的项目中进行使用。
//使用npm加载
npminstallaxios
//使用bower加载
bowerinstallaxios
//使用yarn加载
yarnaddaxios
在这篇文章中,我还是与之前一样,采用下载源文件的方式进行使用,在后续的前端框架搭建完成后再改用前端包管理工具进行加载。
//使用cdn加载
<scriptsrc="https://unpkg.com/axios/dist/axios.min.js"></script>
2、get&post
相比于put请求和delete请求,get请求和post请求是我们最常用的两个方法,一个很常见的使用场景,我们通过get请求来搜索数据,通过post请求来提交数据。
在示例的后端接口中,提供了五个接口方法,分别对应了get、post、put、delete这四个HTTP谓词。put和delete对应的接口方法这里并没有实现,这篇文章主要使用的是get和post谓词对应的三个接口。
2.1、获取所有的用户数据(/api/user)
get请求,加载全部的用户数据,按照创建时间进行降序排列。
2.2、根据搜索条件搜索用户数据(/api/user/query)
get请求,根据用户输入框输入的数据,从全部的用户数据中查找出符合条件的数据,因为这里会存在多个查询条件,其实并不太符合Restful的接口设计,所以这里我采用ASP.NETCore中的特性路由的方式,指定此路由为专门的数据查询接口。
2.3、新增用户数据(/api/user)
post请求,提交一条新的用户数据,因为是采用Restful风格的接口设计,所以请求的地址与获取所有的用户数据相同,仅仅是http谓词的不同。
最终实现的前端页面如下所示,页面第一次加载时会加载全部的用户数据;当用户点击搜索按钮时,会根据顶部的三个输入框中的值,从用户数据中进行筛选;当点击新增按钮时,则会根据Name和Email输入框中的值新增一条新的用户数据。
首先我们需要在页面加载的时候请求后端接口,去获取我们的用户数据,这里我们在Vue实例的methods中定义一个getList方法,在这个方法中我们去请求后端接口。
在之前学习Vue的生命周期钩子函数时我们了解到,在created钩子函数中,对于Vue实例的data和methods已经初始化完成,此时,整个Vue实例已经初始化完成。但是,初始化完成的Vue实例没有与DOM进行绑定。所以,如果我们想要在页面初始加载时就渲染出整个用户信息表格,created函数是能够调用getList方法最早的一个钩子函数。
在axios中,我们发起一个http请求后,在then回掉方法中进行请求成功后的数据处理,在catch回掉方法中捕获请求失败的信息。这里的then方法就相当于我们在Jquery中使用ajax时的success回调方法,而catch方法则是error回调。
axios.get('http://localhost:5000/api/user')
.then(function(response){
console.log(response)
}).catch(function(error){
console.log(error)
})
从接口打印出的返回结果可以看到,接口返回的response中包含了五部分的信息。这里data属性显示的就是整个的用户数据集合,在实际使用中,你需要与http响应状态码进行结合,考虑如果后端出现错误如何使前端知晓,从而相对友好的通知用户。
{
//后端接口返回的数据
data:{},
//服务端接口返回的HTTP状态码
status:200,
//服务端接口返回的HTTP状态信息
statusText:'OK',
//后端接口返回的响应header信息
headers:{},
//axios发起的接口请求时的配置信息
config:{},
//接口响应的请求信息
request:{}
}
针对axios发起请求时的配置信息,我们可以自己进行配置。例如我们可以设置请求的接口域名是什么,设置post请求时的Content-Type,或者针对前后端数据交互时经常使用的JwtToken验证,我们可以在请求的header中添加token信息,从而通过后端的权限验证。
axios.defaults.baseURL='https://api.example.com';
axios.defaults.headers.common['Authorization']=AUTH_TOKEN;
axios.defaults.headers.post['Content-Type']='application/x-www-form-urlencoded';
当我们获取到所有的用户数据后,我们就可以将结果值赋值给我们Vue实例中的users数据集合对象(这个users需要你事先在Vue实例的data中进行提前定义好)。
axios.get('http://localhost:5000/api/user')
.then(function(response){
console.log(response)
this.users=response.data
}).catch(function(error){
console.log(error)
})
如果你按照上面的写法进行赋值,你会发现页面上并没有按照我们的想法渲染出数据。既然我们已经获取到了后端接口返回的数据值,那么这里的问题就可能出现在赋值这上面。我们可以在then回调中打印this.users看看。
可以看到,这里的this指向的其实是浏览器的window对象,因此我们给this.users赋值最终是赋值到window对象上了。因为是this指向出了问题,所以这里我就直接采用箭头函数的方式进行数据赋值,最终的实现代码如下所示。
varvm=newVue({
el:'#app',
data:{
id:'',
name:'',
email:'',
users:[]
},
created(){
this.getList()
},
methods:{
getList(){
axios.get('http://localhost:5000/api/user')
.then(response=>{
this.users=response.data
}).catch(error=>{
console.log(error)
})
}
},
});
搜索按钮的功能与获取所有用户信息的代码比较相似,这里我们需要将搜索的参数添加到get请求中。从下图的浏览器控制台中可以看到,当点击查询按钮之后,我们添加的参数会以query查询字符串的方式添加到请求的url地址上。
varvm=newVue({
el:'#app',
data:{
id:'',
name:'',
email:'',
users:[]
},
methods:{
search(){
axios.get('http://localhost:5000/api/user/query',{
params:{
id:this.id,
name:this.name,
email:this.email,
}
}).then(response=>{
this.users=response.data
}).catch(error=>{
console.log(error)
})
}
},
});
与get请求相似,使用axios发起post请求也是在then回掉方法中获取接口返回值,在catch回掉方法中捕获错误信息。
varvm=newVue({
el:'#app',
data:{
id:'',
name:'',
email:'',
users:[]
},
methods:{
getList(){
axios.get('http://localhost:5000/api/user')
.then(response=>{
this.users=response.data
}).catch(error=>{
console.log(error)
})
},
add(){
axios.post('http://localhost:5000/api/user',{
name:this.name,
email:this.email,
}).then(response=>{
console.log(response)
this.getList()
}).catch(error=>{
console.log(error)
})
}
},
});
就像我们使用jquery发起ajax请求一样,我们可以使用$.ajax/$.post方法去发起一个get/post请求,也可以在$.ajax方法中通过指定请求的type类型来确定我们是以get请求还是post请求的方式执行,在axios中也提供了相似的功能。
//get请求
axios({
method:'get',
url:'http://localhost:5000/api/user'
})
//post请求
axios({
method:'post',
url:'http://localhost:5000/api/user',
data:{
name:this.name,
email:this.email,
}
});
整个前端页面完整的示例代码以及实现的效果如下所示。
<divid="app">
<divclass="cardborder-infomb-3"style="margin-top:20px;">
<divclass="card-headertext-info">
<b>用户信息</b>
</div>
<divclass="card-bodytext-infoform-inline">
<divclass="form-row">
<divclass="form-group">
<divclass="input-groupmb-2mr-sm-2">
<divclass="input-group-prepend">
<divclass="input-group-texttext-info">Id</div>
</div>
<inputtype="text"class="form-control"id="id"v-model="id"autocomplete="off">
</div>
</div>
<divclass="form-group">
<divclass="input-groupmb-2mr-sm-2">
<divclass="input-group-prepend">
<divclass="input-group-texttext-info">Name</div>
</div>
<inputtype="text"class="form-control"id="name"v-model="name"autocomplete="off">
</div>
</div>
<divclass="form-group">
<divclass="input-groupmb-2mr-sm-2">
<divclass="input-group-prepend">
<divclass="input-group-texttext-info">Email</div>
</div>
<inputtype="email"class="form-control"id="email"v-model="email"autocomplete="off">
</div>
</div>
<divclass="form-group">
<aclass="btnbtn-info"href="#"role="button"@click="search">搜索</a>
<aclass="btnbtn-success"href="#"role="button"@click="add">新增</a>
</div>
</div>
</div>
</div>
<tableclass="tabletable-stripedtable-borderedtable-hovertext-info">
<theadclass="thead-inverse">
<tr>
<th>Id</th>
<th>Name</th>
<th>Email</th>
<th>CreatedOn</th>
</tr>
</thead>
<tbody>
<trv-for="iteminusers":key="item.id">
<tdscope="row">{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.email}}</td>
<td>{{item.createdTime}}</td>
</tr>
</tbody>
</table>
</div>
<script>
varvm=newVue({
el:'#app',
data:{
id:'',
name:'',
email:'',
users:[]
},
created(){
this.getList()
},
methods:{
getList(){
axios.get('http://localhost:5000/api/user')
.then(response=>{
this.users=response.data
}).catch(error=>{
console.log(error)
})
},
search(){
axios.get('http://localhost:5000/api/user/query',{
params:{
id:this.id,
name:this.name,
email:this.email,
}
}).then(response=>{
this.users=response.data
}).catch(error=>{
console.log(error)
})
},
add(){
axios.post('http://localhost:5000/api/user',{
name:this.name,
email:this.email,
}).then(response=>{
console.log(response)
this.getList()
}).catch(error=>{
console.log(error)
})
}
},
});
</script>
3、拦截器
在前后端分离的项目中,我们一般采用Jwttoken的方式进行权限控制。前端在获取数据之前,需要从后端获取到token令牌。当前端获取到后端回传的token信息后,我们需要将此token信息保存下来,此后所有的请求都需要在请求的header信息中添加此token信息。那么,能不能有一种方式可以在触发后端验证之前,统一的进行token信息校验,当判断没有包含token信息之后,前端直接跳转到登录页面。
在axios中,我们可以将此类操作放置到拦截器中。你可以将axios中的拦截器看成是ASP.NETCore中的Filters过滤器,例如,这里的需求,我们完全可以将获取到的token信息置于request请求拦截器中,在发起的每一次http请求时去校验是否包含token信息,当没有包含token信息时,就可以直接跳转到登录页面。
这里因为我并没有实现后端token验证,所以这里就只是进行一个演示,你可以从浏览器的控制台中看到只要我们发起一个http请求,就会输出的我们打印的信息。
//request请求拦截
axios.interceptors.request.use(function(request){
//对request进行拦截
if(true){
console.log('跳转到登录页面')
}
returnrequest;
},function(error){
//在错误请求时进行操作
returnPromise.reject(error);
});
既然有针对发起request请求时的拦截器,毫无疑问,对于获取到接口返回的response信息,我们同样可以使用拦截器进行拦截。例如,在定义restful接口时,我们一般会根据http响应状态码去反映接口的调用是否成功。在每一个通过axios发起请求的then回掉方法中,我们都需要对获取到响应状态码进行判断,判断接口的调用是否成功。
当我们使用拦截器后,我们完全可以在针对response的拦截器中进行统一的判断。例如,当调用接口不成功时,http响应状态码为400,同时返回错误信息,我们完全可以在拦截器中进行判断,当所有的接口响应状态码为400时,弹出后端返回的错误信息。
//response请求拦截
axios.interceptors.response.use(function(response){
//对response进行拦截
switch(response.status){
case200:
console.log('接口访问成功')
break
case400:
console.log('提示错误信息')
break
case401:
console.log('重定向到登录页面')
break
}
returnresponse;
},function(error){
//在错误请求时进行操作
returnPromise.reject(error);
});
三、总结
这篇文章主要是简单介绍如何使用axios去实现发起一个http请求。至此,在现阶段的Vue学习使用中,对于一些基础知识点就已经完成了一个初步的梳理,接下来,从下一章开始,我会从0开始通过VueCLI去搭建一个前端的项目模板,因为自己并不是一个前端开发人员,个人的关注点还在于.NETCore后端,所以这里可能并不会涉及到webpack相关的知识点。同时,一些在之前的学习中没有涉及到的知识点也会在后续的文章中进行补充。之后,就像开篇时所说的那样,Vue.js牛刀小试和ASP.NETCore项目实战相辅相成,后期的关注点将聚焦于如何通过ASP.NETCore和Vue进行前后端开发,欢迎持续关注~~~
如果您觉得本文的内容对您的学习有所帮助:
关键字:
hmtl