封装网络请求 http.js
import axios from 'axios'
import qs from 'qs'
// 真实情况下可能会分环境
// 在webpack 会设置一个环境变量
//process.env.NODE_ENV
// 在package.json中的script配置
// "serve:test": "set NODE_ENV=test&&vue-cli-service serve"
//"serve:production": "set NODE_ENV=production&&vue-cli-service serve"
// window电脑用set | MAC(苹果电脑) 把set 和&& 去掉 用空格代替
// 启动服务时 : npm run serve: test 或 npm run serve: production 就是调用不同的接口
// npm run serve 就是调用默认的接口
//根据环境变量区分接口的默认机制
switch(process.env.NODE_ENV){
case "production":
axios.defaults.baseURL = "www.production.com" //请求前缀
break;
case "test":
axios.defaults.baseURL = "www.test.com" //请求前缀
break;
default:
axios.defaults.baseURL = "www.default.com" //默认请求前缀
}
// 设置超时时间
axios.defaults.timeout = 5000
//CORS跨域是否允许携带凭证
//axios.defaults.withCredentials = true //一般设置为true 不然登录用不了cookie,如果自定义凭证,请注释它,不然会造成跨域错误
// 设置post请求头:告知服务器请求主体的数据格式(看服务器要求什么格式)
// 设置请求传递数据的格式
axios.defaults.headers['Content-Type'] = 'application/X-www-form-urlencoded'
axios.defaults.transformRequest = data => qs.stringify(data)
// 设置请求拦截器
// 客户端发送请求 --> [请求拦截器] --> 服务器
// TOKEN 校验(JWT),服务器会把token返回给客户端,(相当于一个标识)
// 存储到vuex或本地存储中,每次向服务器发请求,我们应该把token带上,不然会被标识成非法请求
axios.interceptors.request.use(config => {
let token = localStorage.getItem('token')
token && (config.headers.Authorization = token)
return config
},error => {
// Do something with request error
return Promise.reject(error)
})
// 响应拦截器
// 服务器返回信息 --> [拦截的统一处理] --> 客户端js获取到信息
// 特殊处理有一个配置validateStatus 校验状态码;状态码>200 <300 才算成功 默认情况
// 3开头表示不是永久重定向就是临时重定向,走的协商缓存。
axios.defaults.validateStatus = status => {
// 自定义响应成功的HTTP状态码
return /^(2|3)\d{
2}/.test(status)
}
axios.interceptors.response.use(response => {
// Do something before response is sent
// 成功过后返回响应主体
return response.data
// 或者返回response
//return response
},error => {
// Do something with response error
// 5开头的错误,表示服务器蹦了
let {
response} = error
if(response) {
// => 服务器起码返回结果了
switch(response.status) {
case 401: //当前用户需要验证(一般是未登陆)
break //一般可以弹出遮盖层,或者回到登陆页面
case 403: // 服务器理解请求,但是拒绝执行,一般是token,session过期
break
case 404: // 找不到页面,可以给一个友好的提示
break
}
} else {
// => 服务器连结果都没返回,可能服务器蹦了,或者客户端断网了
if(!window.navigator.onLine) {
// 断网处理: 可以调转到断网页面
return
}
return Promise.reject(error)
}
})
// 导出
export default axios
使用axios封装的方法
建议分模块写请求接口
import axios from './http'
function getTestData(){
return axios.get('/paper/type/all')
}
export default {
getTestData
}
建立一个api.js 来管理所有请求
api.js
//定义数据请求的唯一入口,可以按大模块块来分
import testData from './testData'
export default {
testData
}
调用接口
<template>
<div class="hello">
</div>
</template>
<script>
import api from '../api/api'
export default {
name: 'HelloWorld',
props: {
msg: String
},
methods: {
},
mounted () {
// 原型链全局定义$api 方法
this.$api.testData.getTestData().then(res => {
console.log(res);
});
// 引入api 方式调用接口
api.testData.getTestData().then(res => {
console.log(res);
});
}
}
</script>
<style scoped>
</style>
main.js全局定义
import {
createApp } from 'vue'
import App from './App.vue'
import api from './api/api'
const app = createApp(App)
app.config.globalProperties.$api = api
app.use(api).mount('#app')