Vue Axios开发环境、生产环境跨域问题解决
一、前置知识
首先要了解几个Vue-cli的几个配置参数。另:从 Vue CLI 3.3 起
baseUrl
已弃用,请使用publicPath
1. publicPath
它是部署你的应用包时的基本URL。默认为 '/'
。Vue Cli默认项目是被部署在域名的根路径下。比如你要把打包生成的文件部署在https://www.lhch.com
下,那么采用默认设置就行。
那如果我们是部署在https://www.lhch.com/test/
路径下呢?那么此时可以:
- 设置PublicPath为
/test/
- 设置PublicPath为
./
第二种设置方法是把PublicPath设置为相对路径,所有的资源会被连接为相对路径,这样打出来的包可以被部署在任意路径。如果后面又部署到了https://www.lhch.com/test/index
下,第二种配置方法依然生效。
publicPath在开发环境也会生效,可以根据不同的环境切换publicPath的值:
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? '/test/' : '/',
//或者这样:
publicPath: process.env.NODE_ENV === 'production' ? './' : '/'
}
2. devServer
对于webpack的devServer,Vue Cli的devServer都支持。
比如你要启用gzips
压缩dist/
目录下的所有内容并提供一个9000
本地端口服务:
module.exports = {
//...
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 9000
}
};
如果前端应用跟后台API服务器没有运行在同一台主机,那就需要在开发环境下将API请求代理到API服务器。此时可以通过devServer.proxy
来配置:
module.exports = {
//...
devServer: {
proxy: {
'/api': 'http://localhost:8080'
}
}
};
那么此时对/api/users
的请求会将请求代理到 http://localhost:8080/api/users
如果实际的后台接口不包含 /api
,可以重写路径:
module.exports = {
//...
devServer: {
proxy: {
'/api': {
target: 'http://localhost:8080',
pathRewrite: {'^/api' : ''}
}
}
}
};
pathRewrite
里是个正则语句,意思是将匹配到的以 /api
开头的字符串替换为空。
通俗的讲就是:proxy是一种代理,只要遇到含有’/api’的请求,我就去代理这个请求。至于pathRewrite等其他配置项,只是告诉这个代理怎么去代理这些请求
可能很多同学还会有些疑惑,举个例子:
实际开发中,可能会存在下面的情况:
- 后端给的所有接口会有一个统一的字段,比如:
https://www.lhch.com/api/users
,https://www.lhch.com/api/coustomers
- 后端给的接口并没有上面所说的情况,比如
https://www.lhch.com/users
,https://www.lhch.com/coustomers
针对第一种情况,porxy里配置 '/api': 'https://www.lhch.com'
,当请求 /api/user/
的时,就会被代理到https://www.lhch.com/api/user
针对第二种情况,我正常的接口请求里就没有/api
字段,我又需要代理这些请求,怎么办呢,那就需要使用pathRewrite
将/api
替换为空。当请求 /api/user/
的时候,本来会被代理到https://www.lhch/api/users
, 但是设置pathRewrite: {'^/api' : ''}
,那么这个请求最终就会被代理到https://www.lhch.com/user
更多详细的配置内容,你可以点击查阅下面的官方文档:
Vue的devServer配置详情
webpack的devServer配置详情
修改完配置文件,永远要记得重跑一下项目,不然你会发现,我屮艸芔茻,我的配置怎么都不起作用?
二、开发环境
开发环境的跨域配置,相信你如果认真看了上面的介绍,已经知道怎么做了。
三、生产环境
首先,请始终明白一个道理,配置devServer
不能解决生产环境跨域问题。它解决的是开发环境的跨域问题。
试想一下,项目都开发完成了,也打包了,生成的静态资源都放入服务器了,需要你一个前端来解决跨域问题吗?
这个问题后端分分钟给你解决了。
我目前项目是基于d2-admin,对此,我只需要在.env
生产环境配置文件里配置VUE_APP_API
就好了。
VUE_APP_API=https://www.lhch.com
为什么配置
VUE_APP_API
呢,因为项目对于axios进行了一层封装,其在创建axios实例的时候指定了:baseURL: process.env.VUE_APP_API
。其创建axios实例代码,我贴在下面。
// 创建一个 axios 实例
const service = axios.create({
baseURL: process.env.VUE_APP_API,
timeout: 60 * 1000 // 请求超时时间
})
当然对于我个人项目配置这一块,各位可以当做废话,省去不看。
什么?后端不配合?
什么?后端不会配置允许跨域?
那你可以‘友好的’把下面代码展示给他/她看。(基于spring boot)
public WebMvcConfigurer corsConfigurer()
{
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").
allowedOrigins("*").
allowedMethods("*").
allowedHeaders("*").
allowCredentials(true).
exposedHeaders(HttpHeaders.SET_COOKIE).maxAge(3600L);
}
};
}
如果后端实在懒得给你配置允许跨域,
那你可能需要启动一个nginx服务,并添加一个类似的配置文件nginx.conf
:
server {
...
location /api{
add_header 'Access-Control-Allow-Origin' '*';
proxy_pass https://www.lhch.com/api;
}
...
}
修改完配置文件记得重启nginx.
四、小结
其实问题很简单,奈何有许多像我一样不爱看官方文档,恰巧又碰到了这些跨域问题,无奈只能搜索网上这些解决跨域问题的文章,又恰巧碰到大多数博主连生产环境、测试环境都不分,而写出的一大堆不知所云的东西。
希望看到此文的你,在弄清楚了某些设置背后的原理的同时,也完美的解决了“跨域”问题。
如果此文帮到了你,你可以随意赞赏,以示鼓励。