跨域问题解决方案

引言

跨域问题一般会在前后端分离的项目中遇到,跨域的产生是因为浏览器为了安全设置的同源策略,只有协议(http/https)、域名(www.test.com)、端口(8080/8081…)三者都相同时才不会产生跨域问题;

这也解释了为什么前后端分离的项目会有跨域问题,就比如我们在同一台服务器上开发,前端的url为:http://127.0.0.1:3000,而后端的url为:http://127.0.0.1:8080,两者端口都不同如果相互访问定然会产生跨域问题;

如图:

image-20220706164712128

前端http://localhost:3000向后端发送请求:http://localhost:8080/api/user/search/tags,但是因为端口号不同,于是请求失败,报错信息也显示跨域策略阻塞:has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

下面就分享一下我对于跨域问题的解决方法;

解决方法

下面就是几种方法解决上面案例;

WebMvcConfig配置类跨域配置

可以通过自定义配置类实现跨域请求,具体配置如下:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        // 设置允许跨域的路径
        registry.addMapping("/**")
                // 设置允许跨域请求的域名
                // 当Credentials证书为true时,Origin不能为星号,需为具体的ip地址(如果接口不带cookie,ip无需设成具体ip)
                .allowedOrigins("http://localhost:3000")
                // 是否允许证书 不再默认开启
                .allowCredentials(true)
                // 设置允许的方法
                .allowedMethods("*")
                // 跨域允许时间
                .maxAge(3600);
    }
}

前端向后端请求:

image-20220706170503294

可以看到请求成功,并且跨域允许的url为配置的前端域名:http://localhost:3000

注解@CrossOrigin实现跨域

这个方法比上面方法就简单太多了,直接在后端Controller类上加上该注解,默认允许所有跨域请求,但是最好还是标明请求域名:

image-20220706171124742

这样也可以实现跨域访问,相对于配置来说简单些,但是也有缺点,最后一块说;

结果就不展示了,和之前一样;

GateWay网关配置

网关配置一般是在微服务项目中单独有一个网关模块,因为微服务中的所有请求都要通过网关过滤,所以请求首先就是到网关,我们可以通过在网关服务中配置跨域:

在网关模块的application.yml配置文件中配置跨域:

# 跨域配置:
spring:
  cloud:
    gateway:
      globalcors: # 全局的跨域处理
        add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
        corsConfigurations:
          '[/**]': # 设置拦截哪些请求,/**表示拦截一切请求
            allowedOrigins: # 允许哪些网站的跨域请求 
              - "http://localhost:3000"
            allowedMethods: # 允许的跨域ajax的请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允许在请求中携带的头信息
            allowCredentials: true # 是否允许携带cookie
            maxAge: 360000 # 这次跨域检测的有效期

我们也可以自定义配置文件配置:

/**
 * 跨域统一配置
 */
@Configuration
public class CorsConfig {
    // 处理跨域
    @Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        // 允许的请求头
        config.addAllowedMethod("*");
        // 允许的请求源 (如:http://localhost:8080)
        config.addAllowedOrigin("http://localhost:3000");
        // 允许的请求方法 ==> GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
        config.addAllowedHeader("*");
        // URL 映射 (如: /admin/**)
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/**", config);
        return new CorsWebFilter(source);
    }
}

这两种方法都可以实现网关的跨域配置;

总结

大体上介绍了三种解决跨域的方法,那么实际该如何选择呢?

  • @CrossOrigin注解:这种方法适合单体项目,比较灵活,实现简单;每一个Controller接口允许的跨域url都很清楚,但是Controller接口多了后就很麻烦;

  • WebMvcConfig配置类:这种方法适合单体项目,并且如果你觉得在每一个Controller上添加@CrossOrigin注解很麻烦的话,就可以使用这个方法;

  • GateWay网关配置:这种方法适合微服务项目,并且我分享的两种方法还是比较建议使用第一种方法,直接在application.yml文件配置;
    需要注意一点:如果网关配置了跨域,那么就不要在其他地方配置跨域,比如再在Controller上加@CrossOrigin注解,如果这样跨域相当于没有配置,会失效;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YXXYX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值