SpringBoot跨域解决

2023/11/19 SpringBoot

# SpringBoot跨域解决

# 通用解决

写一个配置类:

继承WebMvcConfigurationSupport或者实现WebMvcConfigurer

# 继承WebMvcConfigurationSupport:

package com.example.manager.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport {
    private final ProjectInterceptor projectInterceptor;
    @Autowired
    public InterceptorConfig(ProjectInterceptor projectInterceptor) {
        this.projectInterceptor = projectInterceptor;
    }
    @Override
    protected void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    // 是否发送Cookie
                    .allowCredentials(true)
                    // 放行哪些原始域 SpringBoot2.4.4下低版本使用.allowedOrigins("*")
                    .allowedOriginPatterns("*")
                    // 放行哪些请求方式
                    .allowedMethods("GET", "POST", "PUT", "DELETE","OPTIONS")
                    // 放行哪些原始请求头部信息
                    .allowedHeaders("*")
                    // 暴露哪些头部信息
                    .exposedHeaders("*");

    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 实现WebMvcConfigurer

package com.example.manager.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                // 是否发送Cookie
                .allowCredentials(true)
                // 放行哪些原始域 SpringBoot2.4.4下低版本使用.allowedOrigins("*")
                .allowedOriginPatterns("*")
                // 放行哪些请求方式
                .allowedMethods("GET", "POST", "PUT", "DELETE","OPTIONS")
                // 放行哪些原始请求头部信息
                .allowedHeaders("*")
                // 暴露哪些头部信息
                .exposedHeaders("*");
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

但是注意,一个项目里两个配置类不能同时存在,也就是有一个类继承了前者,又有一个类实现后者

会导致奇怪的问题,见下文

# 奇怪解决

# 问题

今天配置了拦截器后发现,前端跨域报错了,明明跨域设置好了,项目之前的版本也可以解决跨域,基本确定是拦截器配置类的问题。

然后发现了我的跨域配置类是实现了WebMvcConfigurer,然后另外写了一个配置类配置拦截器,继承了WebMvcConfigurationSupport于是发现项目就不能正常通过跨域了

也就是请求成功了(返回成功代码200)但是缺少同意跨域的响应标头,也就是报下面的错

Access to XMLHttpRequest at 'http://xxx' from origin 'null'

跨域配置类:

package com.example.manager.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                // 是否发送Cookie
                .allowCredentials(true)
                // 放行哪些原始域 SpringBoot2.4.4下低版本使用.allowedOrigins("*")
                .allowedOriginPatterns("*")
                // 放行哪些请求方式
                .allowedMethods("GET", "POST", "PUT", "DELETE","OPTIONS")
                // 放行哪些原始请求头部信息
                .allowedHeaders("*")
                // 暴露哪些头部信息
                .exposedHeaders("*");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

拦截器配置类:

package com.example.manager.config;

import com.example.manager.controller.interceptor.ProjectInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport {
    private final ProjectInterceptor projectInterceptor;
    @Autowired
    public InterceptorConfig(ProjectInterceptor projectInterceptor) {
        this.projectInterceptor = projectInterceptor;
    }

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(projectInterceptor)
                .addPathPatterns("")//添加拦截路径
                //添加不拦截路径
                .excludePathPatterns("/**");
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 解决方案

既然继承两种是一样的

只要把跨域配置方法写到拦截器配置方法里就好了,或者反过来,随便你。

package com.example.manager.config;

import com.example.manager.controller.interceptor.ProjectInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
    private final ProjectInterceptor projectInterceptor;
    
    @Autowired
    public WebMvcConfig(ProjectInterceptor projectInterceptor) {
        this.projectInterceptor = projectInterceptor;
    }

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(projectInterceptor)
                .addPathPatterns("")//添加拦截路径
                //添加不拦截路径
                .excludePathPatterns("/**");
    }

    @Override
    protected void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    // 是否发送Cookie
                    .allowCredentials(true)
                    // 放行哪些原始域 SpringBoot2.4.4下低版本使用.allowedOrigins("*")
                    .allowedOriginPatterns("*")
                    // 放行哪些请求方式
                    .allowedMethods("GET", "POST", "PUT", "DELETE","OPTIONS")
                    // 放行哪些原始请求头部信息
                    .allowedHeaders("*")
                    // 暴露哪些头部信息
                    .exposedHeaders("*");

    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
最后更新于: 2024/2/27 17:14:39