目标: 通过配置vue-cli的代理解决跨域访问的问题
为什么会出现跨域?
当下,最流行的就是前后分离项目,也就是前端项目和后端接口并不在一个域名之下,那么前端项目访问后端接口必然存在跨域的行为
请注意,我们所遇到的这种跨域是位于开发环境的,真正部署上线时的跨域是生产环境的
解决开发环境的跨域问题
vue-cli的配置文件即vue.config.js,这里有我们需要的 代理选项
module.exports = {
devServer: {
// 代理配置
proxy: {
// 这里的api 表示如果我们的请求地址有/api的时候,就出触发代理机制
// localhost:8888/api/abc => 代理给另一个服务器
// 本地的前端 =》 本地的后端 =》 代理我们向另一个服务器发请求 (行得通)
// 本地的前端 =》 另外一个服务器发请求 (跨域 行不通)
'/api': {
target: 'www.baidu.com', // 我们要代理的地址
changeOrigin: true, // 是否跨域 需要设置此值为true 才可以让本地服务代理我们发出请求
// 路径重写
// 默认的路径:target+baseUrl+apiUrl
// 如:www.baidu.com/api/login,如果后端接口就是该路径,就不用写 pathRewrite
pathRewrite: {
// 重新路由 localhost:8888/api/login => www.baidu.com/api/login
'^/api': '' // 假设我们想把 localhost:8888/api/login 变成www.baidu.com/login 就需要这么做
}
},
}
}
}
注意:vue.config.js的改动如果要生效,需要进行重启服务
同时,还需要注意的是,我们同时需要注释掉 mock的加载,因为mock-server会导致代理服务的异常
// before: require('./mock/mock-server.js'), // 注释mock-server加载
开发环境的跨域–应用示例
我们可以在 .env.development和 .env.production定义变量,变量自动就为当前环境的值
基础模板在以上文件定义了变量VUE_APP_BASE_API,该变量可以作为axios请求的baseURL
我们会发现,在模板中,两个值分别为/dev-api和/prod-api
但是我们的开发环境代理是 /api,所以可以统一下
# 开发环境的基础地址和代理对应
VUE_APP_BASE_API = '/api'
# 这里配置了/api,意味着需要在Nginx服务器上为该服务配置 nginx的反向代理对应/prod-api的地址
VUE_APP_BASE_API = '/prod-api'
我们这里生产环境和开发环境设置了不同的值,后续我们还会在生产环境部署的时候,去配置该值所对应的反向代理,反向代理指向哪个地址,完全由我们自己决定,不会和开发环境冲突
2.在request中设置baseUrl
const service = axios.create({
// 如果执行 npm run dev 值为 /api 正确 /api 这个代理只是给开发环境配置的代理
// 如果执行 npm run build 值为 /prod-api 没关系 运维应该在上线的时候 给你配置上 /prod-api的代理
baseURL: process.env.VUE_APP_BASE_API, // 设置axios请求的基础的基础地址
timeout: 5000 // 定义5秒超时
}) // 创建一个axios的实例
3.封装单独的登录接口
// 用户登录
export function userlogin(data) {
// 因为所有的接口都要跨域 表示所有的接口要带 /api
return request.post('/sys/login', data)
}
4.配置代理跨域
// 代理跨域的配置
proxy: {
// 当我们的本地的请求 有/api的时候,就会代理我们的请求地址向另外一个服务器发出请求
'/api': {
target: 'http://ihrm-java.itheima.net/', // 跨域请求的地址,这里不用写api
changeOrigin: true // 只有这个值为true的情况下 才表示开启跨域
}
}
生产环境解决跨域问题
(1)axios配置
在自定义axios配置文件下面通过生产环境以及开发环境进行判断设置baseURL,例如:
import axios from "axios";
axios.defaults.baseURL =
process.env.NODE_ENV === "development" ? "" : "http://8.129.103.157:3000";
其中 http://8.129.103.157:3000为后端服务的地址以及端口号
(2)接口路径配置
一般我们都会在开发时拼接api来配置开发环境下的跨域代理,但是在生产环境上不能出现这种情况,因为后端接口地址没有api。
所以我们应该像配置baseURL一样配置一个全局变量
const base = process.env.NODE_ENV === "development" ? "/api" : "";
使用时:
export function users(data) {
// 用户查询接口
return request({
url: base + "/users",
method: "get",
data: data
});
}