目录
1. 找到 config/index.js 文件中的 proxyTable:{} 将其修改
2. 找到 config/dev.env.js 文件,配置BASE_URL
3. 找到 config/prod.env.js 文件,配置BASE_URL
一、跨域
因为在Vue的开发阶段,基本都是用webpack打包编译,需要node环境本地运行,因而运行的域名为本地的localhost,这个时候调用后端接口就涉及到跨域的问题了。
1.1 ProxyTable
vue 的 proxyTable 是用于开发阶段配置跨域的工具,可以同时配置多个后台服务器跨越请求接口,其真正依赖的npm包是 http-proxy-middleware, 在GitHub上拥有更丰富的配置,可以按需配置
在不考虑后端CROS跨域方案的情况下,前端配置ProxyTable实现跨域请求的用法如下:
1. 找到 config/index.js 文件中的 proxyTable:{}
将其修改
proxyTable: {
'/api': {
target: 'https://tasst.sinoxk.cn', // 这个是你要代理的地址(开发阶段接口地址)
changeOrigin: true, //跨域需要加上这个
pathRewrite: {
'^/api': '' //可以理解为用 / api代表target里的地址
}
}
}
proxyTable支持配置多个接口:
proxyTable: {
'/api': {
target: 'https://tasst.sinoxk.cn', // 这个是你要代理的地址(开发阶段接口地址)
changeOrigin: true, //跨域需要加上这个
pathRewrite: {
'^/api': '' //可以理解为用 / api代表target里的地址
}
},
'/service': {
target: 'https://tasst.sinoxk.cn', // 这个是你要代理的地址(开发阶段接口地址)
changeOrigin: true, //跨域需要加上这个
pathRewrite: {
'^/service': '' //可以理解为用 / api代表target里的地址
}
}
}
2. 找到 config/dev.env.js 文件,配置BASE_URL
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
BASE_URL:'"/api"' //开发环境域名
})
3. 找到 config/prod.env.js 文件,配置BASE_URL
module.exports = {
NODE_ENV: '"production"',
BASE_URL:'"https://asst.sinoxk.com"' //生产环境保持正式域名
}
4. 配置 axios 的基础域名
axios.defaults.baseURL = process.env.BASE_URL
修改完所有的配置文件后,要注意,需要重启下环境
npm run dev / npm run start
二、封装
在日常项目开发过程中,在和后台交互获取数据的时候,我们都需要使用到网络库,通常在vue的项目中 ,使用的是 axios 库 ,在此基于自身项目业务,做一个二次封装。
1.1 条件准备
在UI轻提示组件上,选定的是 vant 库中的 Toast 组件(Vant文档),可按实际需要选定具体要使用的UI框架
安装:
npm install vant --save
数据序列化,如果有实际需要的项目,可以使用qs
,在这里做一个简单的介绍
安装:
npm install qs --save
qs.stringify和JSON.stringify的使用和区别:
qs.stringify()将对象 序列化成URL的形式,以&进行拼接
JSON.stringify 是将对象转化成一个json字符串的形式
用法:
var a = {name:'xiaoming',age:10}
qs.stringify(a); //log: 'name=xiaoming&age=10'
JSON.stringify(a) //log: '{"name":"hehe","age":10}'
基于底层配置和业务接口分离,在src目录中会新建文件夹 httpServer,同时新建立 ajax.js 和 api.js 文件
ajax.js: axios的二次封装,作为基础网络库,添加基础的配置
api.js: 管理项目实际业务基础接口的输出,以及返回响应数据的处理
在日常项目模块中,基于多人开发,当然可以在api.js的基础上,可以根据功能模块实现业务拓展延伸,比如
小明负责list模块业务
新建api-list.js,并导入api.js ....
//api-list.js文件中:
import api from './api'
export default {
getList(url,params){
api.get(url,params)
}
}
对于个别项目,可能存在多个域名配置的情况下, 可以重新建立 base.js , 来管理多个接口域名
base.js:
/**
* 接口域名的管理
*/
const base = {
sq: 'https://xxxx111111.com/api/v1',
bd: 'http://xxxxx22222.com/api'
}
export default base;
2.2 axios封装(单域名)
src/main.js文件:
import Vue from 'vue'
import App from './App'
import router from './router'
import Api from './httpServer/api'
//挂载到vue的全局属性上
Vue.prototype.$https = Api
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
src/httpServer/ajax.js文件:
import axios from 'axios'
import {Toast} from 'vant'
const ajax = axios.create({
timeout:60000,
baseURL:process.env.BASE_URL //基础域名
})
/**
* 请求拦截器
* 每次请求前,如果存在token则在请求头中携带token
*/
ajax.interceptors.request.use(
config => {
//判断token(根据实际情况拦截)
return config;
},
error => Promise.error(error)
)
/**
* 响应拦截器
*/
ajax.interceptors.response.use(
// 请求成功
res => res.status === 200 ? Promise.resolve(res) : Promise.reject(res),
error => {
const {response} = error;
if (response) { // 请求已发出,但是不在2xx的范围
Toast({message: response.message});
return Promise.reject(response);
} else {
// 处理断网的情况
// eg:请求超时或断网时,更新state的network状态
// network状态在app.vue中控制着一个全局的断网提示组件的显示隐藏
// 关于断网组件中的刷新重新获取数据,会在断网组件中说明
Toast({message: '网络开小差,请稍后重试'});
}
}
)
export default ajax;
对于process.env.BASE_URL的配置,在开发环境中,需要以代理的方式进行访问:
//config/dev.env.js
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
BASE_URL:'"/api"' //对api进行处理
})
//config/prod.env.js
'use strict'
module.exports = {
NODE_ENV: '"production"',
BASE_URL:'"https://www.xxx.com"' //生产环境不需要处理
}
//config/index.js
...
proxyTable: {
'/api': {
target: 'https://tasst.sinoxk.cn',//后端接口地址
changeOrigin: true,//是否允许跨越
pathRewrite: {
'^/api': '',//重写(接口地址带api会被替换)
},
}
},
...
src/httpServer/api.js文件:
import ajax from './ajax'
import {Toast} from 'vant'
/**
* 业务接口成功或者失败的情况处理
*
*/
const handleResponse = (res, success, failure) => {
switch (res.code) {
case 200: //成功
success && success(res.data);
break;
case 401: //登录token失效
break;
default:
if (failure) {
failure(res);
} else {
Toast({message:res.msg || '请求失败,请稍后重试!'});
}
break;
}
}
export default {
get: function (url, params, success, failure) {
ajax.get(url, {
params: params
}).then(res => {
if (res.status == 200) {
handleResponse(res.data.data, success, failure);
}
});
},
post: function (url, params, success, failure) {
ajax.post(url, params).then(res => {
if (res.status == 200) {
handleResponse(res.data.data, success, failure);
}
})
}
}
在src/components/HelloWorld.vue文件中使用:
<script>
export default {
name: 'HelloWorld',
data() {
return {
msg: 'Welcome to Your Vue.js App'
}
},
created() {
//请求接口数据
this.$https.get('/xkzx/member/service', {
pageNum: 1,
pageSize: 10
}, function (data) { //成功
console.log(data);
}, function (res) { //失败
})
}
}
</script>