在测试前期阶段 mock data 的确很有用。可测试后期和线上的时候,就需要用到真实环境数据。
操作一波
关掉 mock
vue.config.js
# 注释掉这几行
// devServer: {
// port: port,
// open: true,
// overlay: {
// warnings: false,
// errors: true
// },
// before: require('./mock/mock-server.js')
// },
src/main.js
# 注释掉这几行
// if (process.env.NODE_ENV === 'production') {
// const { mockXHR } = require('../mock')
// mockXHR()
// }
到此,mock data 已经关掉了。然后运行 npm run dev
或 npm run build:prod
跑起来看看。打开网页,F12 打开控制台,选择 network, 选择 xhr。默认会进入到登录页面(刚运行没登录),输入用户名和密码,点击登录,这个时候,就可以看到请求地址了。地址是下边这样的。而这些只是在打包阶段。
http://192.168.1.141:8080/dev-api/vue-element-admin/user/login
既然我们禁用了 mock data,那我们怎么很好的控制请求了。vue-element-admin 这里使用了 axios,既然是 axios,那就可以去实现拦截器。
修改拦截器
axios 封装在 src/utils/request.js 中了。
** 先看 baseURL **
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests
timeout: 5000 // request timeout
})
baseURL 控制的是请求 api 的地址的前半截(协议 + 域名 + 修饰),比如: http://192.168.1/141:8080/dev-api
在看代码里 process.env.VUE_APP_BASE_API 这个是根据你运行的命令不同调用的配置不同而操作的。也可以说是通过环境变量来控制。假如运行的是 npm run dev
,对应的就是 .env.development
文件。值是 VUE_APP_BASE_API 这个。如果是运行的 npm run build:prod
,对应的就是 .env.production
。
分别修改 .env.development 和 .env.production 文件
# .env.development
VUE_APP_BASE_API = 'http://localhost:8080/admin/api/'
# .env.production
VUE_APP_BASE_API = 'http://jk.cn/admin/api/'
到此,api 请求的 baseURL 修改完毕。
回到正点,增加拦截器。拦截器分请求拦截器和反馈拦截器,和后端的中间件思想类似。
我们先来修改请求拦截器。这里是前后端分离项目,如果做 APP,小程序也是前后端分离。这个时候,后端的授权就是一个很重要的环节。这里,后端我们使用 Sanctum 来做认证,而且是基于 apa,cookie 的方式。而如果做小程序,app 这些,接口的授权将会是基于 Sanctum 的令牌 token 的方式,这里先不讨论。
既然是基于 cookie 的方式,那么将 axios 设置 axios.defaults.withCredentials = true
即可。请求拦截器可不用处理。
# 去掉 withCredentials 注释
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
withCredentials: true, // send cookies when cross-domain requests
timeout: 5000 // request timeout
})
再来看反馈拦截器。
正常返回直接返回,非正常返回中 401 的时候,授权失败需要重新登录,其他则提示。
// response interceptor
service.interceptors.response.use(
/**
* If you want to get http information such as headers or status
* Please return response => response
*/
/**
* Determine the request status by custom code
* Here is just an example
* You can also judge the status by HTTP Status Code
*/
response => {
return response.data
},
error => {
console.log('err' + error) // for debug
if (error.response && error.response.status == 401) {
store.dispatch('logout');
if(router.currentRoute.name != "/login"){
router.push({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
});
}else{
router.push('/login');
}
} else {
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
}
)
修改登录等相关接口
我们遵循 RESTful 设计接口的原则来修改和简化接口名称。可参考以下链接。
https://learnku.com/articles/13631/resetful-api-design-specification
https://learnku.com/articles/13797/restful-api-best-practice
https://learnku.com/articles/9126/writing-more-descriptive-restful-api
先修改 src/api/user.js
import request from '@/utils/request'
export function login(data) {
return request({
url: '/login',
method: 'post',
data
})
}
export function getInfo(token) {
return request({
url: '/user/info',
method: 'get',
params: { token }
})
}
export function logout() {
return request({
url: '/user/logout',
method: 'post'
})
}
最好,mock data 里边的接口名也跟着一起改。如何后边用到的话,这样会方便很多。
再 run,再观察。
下一步
前端页面处理好了,后边就处理服务端了。建立服务端路由以及模型控制器等逻辑。