Vue 前后端数据交互 axios 发起请求、全局默认配置
(前端调后端,后端是有鉴权逻辑的,前端要加一个token,前端在登入的时候就获取到这个token了,每次发起请求的时候这个token加入到url参数内)发起数据请求(每个页面的数据都是活的,不可能数据发生变化的时候都去更新代码),如果每次都填写完整的请求路径,不利于后期维护。正常情况下打开一个浏览器,前端页面向后端页面发起请求,使用的是aixos发起请求,无论是原装的还是封装的axios,后端去数
Axios 介绍
官方文档: http://www.axios-js.com/zh-cn/docs/
Axios 使用
GET、POST 请求 axios.get().then()
axios拿到的数据通过return里面的数据暴露出来
<template>
<div>
<button type="button" @click="getData()">AxiosGet</button><br>
axios get获取到的数据:<p style="color: red;">{{ resdata }}</p>
</div>
</template>
<script>
//导入axios,取别名为axios为下面使用
import axios from 'axios'
export default ({
data() {
return{
resdata: {
}
}
},
methods:{
getData(){
//使用axios发起HTTP get请求
axios.get('http://httpbin.org/get')
//then表示http请求成功情况下,拿到响应,response是响应内容
.then(response=>{
this.resdata = response
}
)
}
}
})
</script>
在main.js当中,全局导入组件
import { createApp } from 'vue'
import App from './App.vue'
import Test from '@/components/Test.vue'
import Home from '@/components/Home.vue'
const vm = createApp(App)
vm.component('Test',Test)
vm.component('Home',Home)
vm.mount('#app')
App.vue当中全局导入Home组件
<template>
<img alt="Vue logo" src="./assets/logo.png">
<Home></Home>
<HelloWorld msg="父亲组件App 子组件HelloWorld" />
</template>
如果是post请求
axios.post('http://httpbin.org/post')
如果需要打开页面就触发拿到数据,打开刷新就能够执行,可以将其放到mouted()回调函数里面,
<script>
import axios from 'axios'
export default {
data(){
return {
backendData: ''
}
},
props:{
msgFather: String
},
mounted() {
this.getBackendData()
},
methods: {
btn(){
this.$emit('childEvent','子组件传给父组件数据啦')
},
getBackendData(){
//使用axios发起HTTP get请求
axios.get('http://httpbin.org/get')
//then表示http请求成功情况下,拿到响应,response是响应内容
.then(response=>{
this.backendData = response
}
)
}
},
}
</script>
post请求其实也是一样,其实就是将一个对象提交过去就行了,后端接收到数据进行处理入库就可以了。第一个是接口参数,第二个是提交过去的数据。
异常处理 axios.get().then().catch()
很多时候我们可能并没有从 API 获取想要的数据。这可能是由于很多种因素引起的,比如 axios 调用可能由于多种原因而失败,包括但不限于:
- API 不工作了
- 请求发错了
- API 没有按我们预期的格式返回信息。
可以使用catch异常处理这些问题, 模拟连接一个不存在的地址,前段给出提示:
<template>
<div class="box">{{ msgFather }}</div>
<button type="button" @click="btn()">子传父</button>
<p>backendData:{{ backendData }}</p>
<p style="color: red;" v-if="notice">{{ errorMsg }}</p>
</template>
<script>
import axios from 'axios'
export default {
data(){
return {
backendData: '',
errorMsg: '',
notice: false
}
},
props:{
msgFather: String
},
mounted() {
this.getBackendData()
},
methods: {
btn(){
this.$emit('childEvent','子组件传给父组件数据啦')
},
getBackendData(){
//使用axios发起HTTP get请求
axios.get('http://httpbin.org/get')
//then表示http请求成功情况下,拿到响应,response是响应内容
.then(response=>{
this.backendData = response
}
)
.catch(error=>{
console.log(error)
this.errorMsg = error.message
this.notice = true
})
}
},
}
</script>
还有一个能力是无论成功与否,都会执行,有一个finally。
axios.post('http://httpbin.org/post1')
//then表示http请求成功情况下,拿到响应,res是响应内容
.then(response=>{
this.resdata = response
}
)
.catch(response=>{
alert(response.message)
console.log(response.message)
})
.finally(()=>{
console.log("最后执行的内容")
})
全局默认值 一般情况下不这么使用
在实际开发中,几乎每个组件都会用到axios发起数据请求(每个页面的数据都是活的,不可能数据发生变化的时候都去更新代码),如果每次都填写完整的请求路径,不利于后期维护。这时可以设置全局axios默认值。
//导入vue依赖当中的createApp方法,这里的createApp是原生方法名称,不能改
import { createApp } from 'vue'
import App from './App.vue'
//导入组件,这种方式是将整个Test.vue界面都导入进来,这里的Test是别名可以随便取
import Test from '@/components/Test.vue'
//添加axios全局配置
//1 引入axios
import axios from 'axios'
//2 设置axios的全局配置
axios.defaults.baseURL = 'http://httpbin.org'
axios.defaults.timeout = 5000
const app = createApp(App)
//使用component去注册组件,第一个参数是组件名称,自定义,第二个是上面定义的组件import Test from
app.component('Test',Test)
app.mount('#app')
<template>
<div>
<button @click="getData()">axios获取后端数据</button>
<p>{{ data }}</p>
</div>
</template>
<script>
//导入aixos
import axios from 'axios'//'axios'是正真的第三方包,axios是别名
export default({
data() {
return{
data: ''
}
},
methods:{
getData(){
//设置了全局的baseUrl后
//使用axios发起http的get请求,发起axios请求,它会去和默认的baseURL做拼接
axios.get('/get')
// axios.get('http://httpbin.org/get')
//then表示http请求成功情况下,拿到响应,res是响应内容
.then(res =>{
this.data = res.data
})
.catch(res=>{
alert(res.message)
})
//无论成功与否
.finally(res=>{
console.log("这是最后执行的命令")
})
}
}
})
</script>
可以看到,会去做自动的拼接。
自定义实例默认值
也可以对axios做自定义实例,它可以满足更加多的个性化配置需求,比如拦截器。
有时候服务端接口有多个地址,就会涉及请求的域名不同、配置不同等,这时自定义实例可以很好解决。
上面这种全局默认值一般不使用,我们要自己去封装一个axios,使用下面方式,这里这个文件会去封装axios。下面其实就是一个vue独立的模块了,可以直接去使用了。
//封装axios
//做一些全局配置,以及拦截器的配置
import axios from "axios";
//实例化axios对象
const instance = axios.create({
baseURL: 'http://httpbin.org',
timeout: 5000,
})
//暴露新的axios实例
export default instance
在src目录下面创建一个request的文件夹。
做全局配置和拦截器的配置
//封装axios
//做一些全局配置,以及拦截器的配置
import axios from "axios";
//实例化axios对象
const instance = axios.create({
baseURL: 'http://httpbin.org',
timeout: 5000,
})
//暴露新的axios实例
export default instance
<template>
<div>
<button @click="getData()">axios获取后端数据</button>
<p>{{ data }}</p>
</div>
</template>
<script>
//导入aixos
//import axios from 'axios'//'axios'是正真的第三方包,axios是别名
import http from '@/request'
export default({
data() {
return{
data: ''
}
},
methods:{
getData(){
//使用新的axios实例发起请求
http.get("/get")
//设置了全局的baseUrl后
//使用axios发起http的get请求,发起axios请求
// axios.get('/get')
// axios.get('http://httpbin.org/get')
//then表示http请求成功情况下,拿到响应,res是响应内容
.then(res =>{
this.data = res.data
})
.catch(res=>{
alert(res.message)
})
//无论成功与否
.finally(res=>{
console.log("这是最后执行的命令")
})
}
}
})
</script>
一般都是使用上面这种方式去封装axios,自己封装或者从其他项目里面copy过来、
上面通过index.js对axios做了一个封装,相当于封装了一个模块。
axios最重要的功能 拦截器
正常情况下打开一个浏览器,前端页面向后端页面发起请求,使用的是aixos发起请求,无论是原装的还是封装的axios,后端去数据库中拿数据返回给前端。
发起请求的地方是axios,你那个自己封装axios,那么你就可以添加拦截器。
请求拦截器就是你在发起请求的时候要做什么事情,响应拦截器就是在接受到请求之后,去干嘛干嘛。
- 拦截器可以拦截每一次请求和响应,然后进行相应的处理。(前端调后端,后端是有鉴权逻辑的,前端要加一个token,前端在登入的时候就获取到这个token了,每次发起请求的时候这个token加入到url参数内)
- 请求拦截应用场景: 发起请求前添加header (token认证信息)
- 统一处理API响应状态码200或非200的提示消息(拿到业务的状态码做一些自定义的响应配置)
- 统一处理catch异常提示信息
- src/request/index.js 示例代码
//请求拦截器
instance.interceptors.request.use(config=>{
//在请求发送之前做些什么事情,主要是发送token
},error=>{
}
)
instance.interceptors.response.use(res=>{
//在服务器响应之后做些什么事情
},error=>{
}
)
可以在里面添加自己的逻辑进行处理
//封装axios
//做一些全局配置,以及拦截器的配置
import axios from "axios";
//实例化axios对象
const instance = axios.create({
baseURL: 'http://httpbin.org',
timeout: 5000,
})
//添加请求拦截器,config接受参数的方式,随意命名
instance.interceptors.request.use(config=>{
//在请求发送之前做的事情,比如添加请求头
config.headers['Test-Header'] = 'zangsan'
return config
},
//请求发生了error
error=>{
//处理错误请求
//axios是基于ajax和promise封装的
//promise.reject就表示使用instance发起请求的时候,失败了在catch中获取错误
return Promise.reject(error)
}
)
//添加响应拦截器
instance.interceptors.response.use(res=>{
//响应接收后做的事情,在then catch finally之前做的事情
if(res.status != 200){
alert("数据请求失败")
}
return res
},
error =>{
//非200状态码走这里
return Promise.reject(res)
}
)
//暴露新的axios实例
export default instance
访问apiserver,用户认证从api当中返回token放到本地存储里面,每次携带这个token去访问。
import axios from "axios";
const instance = axios.create({
baseURL: 'http://httpbin.org',
timeout: 5000,
})
instance.interceptors.request.use(config=>{
//在发送之前要从本地去获取这个token
const token = window.sessionStorage.getItem('token')
//如果拿到token了,那就说明登入了,在header里面要将这个token放进去
//例如:每次访问api都携带token
if (token){
config.headers = {
'Authorization': 'Token ' + token
}
}
return config; //修改之后的数据返回回去
},error=>{
//访问不到api服务器做什么?
return Promise.reject(error)
})
instance.interceptors.response.use(res=>{
},error=>{
//非用户定义错误返回,原生的http方式返回
//访问到API服务器,但是响应失败做些什么
return Promise.reject(error)
})
export default instance
更多推荐
所有评论(0)