目录
方法一、直接采用SpringBoot的注解@CrossOrigin(也支持SpringMVC)
方法二、采用过滤器(filter)的方式 增加一个配置类,给容器中注册一个bean
方法三、继承WebMvcConfigurerAdapter或者实现WebMvcConfigurer接口。
什么是跨域问题?
CORS跨域问题,是当前主流web开发人员都绕不开的难题。但我们首先要明确以下几点
-
跨域只存在于浏览器端,不存在于安卓/ios/Node.js/python/ java等其它环境
-
跨域请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。
-
之所以会跨域,是因为受到了同源策略的限制,同源策略要求源相同才能正常进行通信,即协议、域名、端口号都完全一致。
浏览器出于安全的考虑,使用 XMLHttpRequest对象发起 HTTP请求时必须遵守同源策略,否则就是跨域的HTTP请求,默认情况下是被禁止的。换句话说,浏览器安全的基石是同源策略。
什么是CORS?
CORS是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing),允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
它通过服务器增加一个特殊的Header[Access-Control-Allow-Origin]来告诉客户端跨域的限制,如果浏览器支持CORS、并且判断Origin通过的话,就会允许XMLHttpRequest发起跨域请求。
解决CORS跨域问题
方法一、直接采用SpringBoot的注解@CrossOrigin(也支持SpringMVC)
简单粗暴的方式,Controller层在需要跨域的类或者方法上加上该注解即可,要求在Spring4.2及以上的版本
@RestController @CrossOrigin @RequestMapping("/situation") public class SituationController extends PublicUtilController { @Autowired private SituationService situationService; // log日志信息 private static Logger LOGGER = Logger.getLogger(SituationController.class); }
方法二、采用过滤器(filter)的方式 增加一个配置类,给容器中注册一个bean
@Configuration public class CorsFilterConfig { @Bean public CorsFilter corsFilter() { // 1.添加CORS配置信息 CorsConfiguration config = new CorsConfiguration(); // 放行哪些原始域 config.addAllowedOrigin("*"); // 是否发送Cookie信息 config.setAllowCredentials(true); // 放行哪些原始域(请求方式) config.addAllowedMethod("*"); // 放行哪些原始域(头部信息) config.addAllowedHeader("*"); // 暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息) config.addExposedHeader("*"); // 2.添加映射路径导入配置 UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource(); configSource.registerCorsConfiguration("/**", config); // 3.返回新的CorsFilter. return new CorsFilter(configSource); } }
方法三、继承WebMvcConfigurerAdapter或者实现WebMvcConfigurer接口。
继承WebMvcConfigurerAdapter或者实现WebMvcConfigurer接口,其他都不用管,项目启动时,会自动读取配置 (已经不建议使用了)。
-
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class CorsConfig extends WebMvcConfigurerAdapter { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*")//allowedOriginPatterns("*") .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS") .allowCredentials(true) .maxAge(3600) .allowedHeaders("*"); }
方法四、采用nginx做动态代理 ,解决跨域问题
1)修改nginx配置文件:
location /api/ { proxy_pass http://localhost:88/; #这里是nginx接受到请求后代理给后端的地址 }
2) 让前端请求nginx开放的端口(默认是80端口)
比如:前端发送请求:http://localhost:80/api/hello 经过nginx代理,后端收到的实际请求是:http:localhost:88/hello.
方法五:前端配置代理的方式,这里已vue3为例
前端在发送请求的时候加上一个统一的前缀 '/api'。
然后在vite.config.js文件中的server中配置Proxy
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import { Server } from 'node:http'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
server:{
//设置服务端口
port:7000,
//配置代理
proxy:{
'/api': {
target: 'http://localhost:8081', // 后端服务器地址
changeOrigin: true, // 是否改变请求域名
rewrite: (path) => path.replace(/^\/api/, '')//将原有请求路径中的api替换为''
}
}
}
})
注意,在一个微服务中,不能存在多个cors配置类,不然也会出现错误,前端照样得不到结果。