Ⅱ又贝人韦 Ⅱ又贝人韦
首页
JAVA
Golang
  • Spring
  • 日志框架
  • MySQL
  • 全链路跟踪
  • 资源
  • MAC使用技巧
GitHub (opens new window)
首页
JAVA
Golang
  • Spring
  • 日志框架
  • MySQL
  • 全链路跟踪
  • 资源
  • MAC使用技巧
GitHub (opens new window)
  • Spring Boot+VUE 前后端分离跨域配置
    • CORS介绍:
    • SpringBoot配置跨域
    • Access-Control-Allow-Credentials及 Access-Control-Allow-Origin配置
  • Spring
shixw
2021-10-08
目录

Spring Boot+VUE 前后端分离跨域配置

# CORS介绍:

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS (opens new window)

# SpringBoot配置跨域

配置类型:org.springframework.web.servlet.config.annotation.WebMvcConfigurer

@Override
public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**")
            .allowedOrigins("*")
            .allowedHeaders("*")
            .allowCredentials(true)
            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS");
 
}
1
2
3
4
5
6
7
8
9

# Access-Control-Allow-Credentials及 Access-Control-Allow-Origin配置

在阅读CORS介绍是发现如果一段介绍,针对需要附带身份凭证的请求的一个介绍,如下:

附带身份凭证的请求与通配符 ( Access-Control-Allow-Credentials: true)对于附带身份凭证的请求,服务器不得设置 Access-Control-Allow-Origin 的值为“”。 这是因为请求的首部中携带了 Cookie 信息,如果 Access-Control-Allow-Origin 的值为“”,请求将会失败。而将 Access-Control-Allow-Origin 的值设置为 http://foo.example,则请求将成功执行。

如上介绍所说和我们后端代码中的配置不太一致,猜想Spring做了处理,所以对这块的处理代码进行阅读,发现spring流程大致如下,确实帮我们处理了这种情况,如下

关键代码:

  1. 判断是否跨域请求
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
 
package org.springframework.web.cors;
 
import javax.servlet.http.HttpServletRequest;
import org.springframework.http.HttpMethod;
 
public abstract class CorsUtils {
    public CorsUtils() {
    }
 
    public static boolean isCorsRequest(HttpServletRequest request) {
        return request.getHeader("Origin") != null;
    }
 
// 判断是否为预检请求
    public static boolean isPreFlightRequest(HttpServletRequest request) {
        return isCorsRequest(request) && HttpMethod.OPTIONS.matches(request.getMethod()) && request.getHeader("Access-Control-Request-Method") != null;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  1. org.springframework.web.cors.DefaultCorsProcessor 处理 Access-Control-Allow-Credentials: true 时 Access-Control-Allow-Origin * 问题

public boolean processRequest(@Nullable CorsConfiguration config, HttpServletRequest request, HttpServletResponse response) throws IOException {
    if (!CorsUtils.isCorsRequest(request)) {
        return true;
    } else {
        ServletServerHttpResponse serverResponse = new ServletServerHttpResponse(response);
        if (this.responseHasCors(serverResponse)) {
            logger.trace("Skip: response already contains \"Access-Control-Allow-Origin\"");
            return true;
        } else {
            ServletServerHttpRequest serverRequest = new ServletServerHttpRequest(request);
            if (WebUtils.isSameOrigin(serverRequest)) {
                logger.trace("Skip: request is from same origin");
                return true;
            } else {
                boolean preFlightRequest = CorsUtils.isPreFlightRequest(request);
                if (config == null) {
                    if (preFlightRequest) {
                        this.rejectRequest(serverResponse);
                        return false;
                    } else {
                        return true;
                    }
                } else {
                    return this.handleInternal(serverRequest, serverResponse, config, preFlightRequest);
                }
            }
        }
    }
}
 
 
protected boolean handleInternal(ServerHttpRequest request, ServerHttpResponse response, CorsConfiguration config, boolean preFlightRequest) throws IOException {
    String requestOrigin = request.getHeaders().getOrigin();
    String allowOrigin = this.checkOrigin(config, requestOrigin);
 
 
 
 
@Nullable
protected String checkOrigin(CorsConfiguration config, @Nullable String requestOrigin) {
    return config.checkOrigin(requestOrigin);
}
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
43

3.org.springframework.web.cors.CorsConfiguration#checkOrigin

@Nullable
public String checkOrigin(@Nullable String requestOrigin) {
    if (!StringUtils.hasText(requestOrigin)) {
        return null;
    } else if (ObjectUtils.isEmpty(this.allowedOrigins)) {
        return null;
    } else if (this.allowedOrigins.contains("*")) {
        return this.allowCredentials != Boolean.TRUE ? "*" : requestOrigin;
    } else {
        Iterator var2 = this.allowedOrigins.iterator();
 
        String allowedOrigin;
        do {
            if (!var2.hasNext()) {
                return null;
            }
 
            allowedOrigin = (String)var2.next();
        } while(!requestOrigin.equalsIgnoreCase(allowedOrigin));
 
        return requestOrigin;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

##自定义拦截器时跨域相关配置时效处理

原因: 原因是请求经过的先后顺序问题,当请求到来时会先进入拦截器中,而不是进入Mapping映射中,所以返回的头信息中并没有配置的跨域信息。浏览器就会报跨域异常。

配置方式: 使用CorsFilter过滤器,如下:


private CorsConfiguration corsConfig() {
    CorsConfiguration corsConfiguration = new CorsConfiguration();
    * 请求常用的三种配置,*代表允许所有,当时你也可以自定义属性(比如header只能带什么,只能是post方式等等)
    */
    corsConfiguration.addAllowedOrigin("*");
    corsConfiguration.addAllowedHeader("*");
    corsConfiguration.addAllowedMethod("*");
    corsConfiguration.setAllowCredentials(true);
    corsConfiguration.setMaxAge(3600L);
    return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", corsConfig());
    return new CorsFilter(source);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
编辑 (opens new window)
上次更新: 2021/10/08, 15:02:58
最近更新
01
相关资源
11-23
02
Java线程池常用配置
07-23
03
binlog常用操作命令
07-23
更多文章>
Theme by Vdoing | Copyright © 2021-2022 shixw | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式