什么是跨域问题?
就是你在浏览器访问前端项目时,控制台报出的错,如下图:
再次重申一遍,跨域问题只出现在本地开发过程中,在运维环境中不会出现跨域问题
解决方式一:后端 @CrossOrigin 注解
可以在 Controller
类上添加 @CrossOrigin
注解,则这个 Controller 类中的所有包含(@XxxMapping
)的方法都可以正常访问。
也可以直接将该注解放在具体的方法上,指定某个方法可跨域访问。
可以设置一个全局 Controller
父类,添加该注解,然后所以的业务 Controller
类继承该类,以实现全局跨域。
还是较麻烦的,不推荐使用。
有关 @CrossOrigin
注解更多内容可参考博客 注解 @CrossOrigin 详解
解决方式二:后端解决(已弃用,不推荐)
在你的后端项目里新建一个 XxxConfig
类,实现 WebMvcConfigurerAdapter
接口,并覆盖其中的 addCorsMappings
方法,即可解决开发环境中的跨域问题。该配置类源码如下:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
解决方式三:后端解决(通用,推荐)
在你的后端项目里新建一个 XxxConfig
类,实现 WebMvcConfigurer
接口,并覆盖其中的 addCorsMappings
方法,即可解决开发环境中的跨域问题。该配置类源码如下:
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.maxAge(3600);
}
}
题外话:关于上文提到的 WebMvcConfigurerAdapter、WebMvcConfigurer 以及 WebMvcConfigurationSupport 之间的关系
- WebMvcConfigurerAdapter 是 Spring 内部的一种配置方式,采用 JavaBean 的形式来代替传统的 xml 配置文件形式进行针对框架个性化定制,例如跨域问题、拦截器、视图解析器、静态资源控制等。
- 在 Spring Boot 2.0 后继承 WebMvcConfigurerAdapter 时,idea 会提示这个类已经过时了。通常情况下我们会采用下面两种代替方案:
- 实现 WebMvcConfigurer
- 继承 WebMvcConfigurationSupport
- 但是继承 WebMvcConfigurationSupport 时会造成一些问题,这个类很霸道,具体不再阐述。
- 更多三者的内容可参考相关官方文档、或 WebMvcConfigurer 与 WebMvcConfigurationSupport 避坑指南。
解决方式四:前端解决
在 vue 项目根目录里的 vue.config.js
(没有则新建)文件里添加:
// 跨域配置,这个在开发环境中生效,如果使用 npm run build 打包后没效
module.exports = {
devServer: { //记住,别写错了devServer
port: 8080, //设置本地默认端口
proxy: { //设置代理,必须填
'/api': { //设置拦截器 拦截器格式=>斜杠+拦截器名字,名字可以自己定
target: 'http://localhost:8081', //代理的目标地址
changeOrigin: true, //是否设置同源,输入是的
pathRewrite: { //路径重写
'/api': '' //选择忽略拦截器里面的单词
}
}
}
}
}
注意,以上配置后,在前端 axios
调用后端接口时,需要在路径最前方带上 /api
,例如查询所有元数据的后端服务接口为
http://localhost:8081/metadata
,原来在前端项目里我们需要写成 /metadata
即可,现在需要写成 /api/metadata
前端解决跨域问题后,后端无需再解决。