# 描述

前端向后端发送请求浏览器控制台报错:

Access to XMLHttpRequest at ‘http://localhost:8082/doLogin’ from origin ‘http://localhost:8080’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

# 跨域

浏览器出于安全考虑,限制访问本站外的资源。
跨域访问(Cross-Origin Resource Sharing)通过在服务器端设置响应头,把发起跨域的原始域名添加到 Access-Control-Allow-Origin 请求头字段。
源(Origin)就是协议、域名和端口。如果两个 URL 的协议、域名和端口全部相同,就是同源。否则,只要协议、域名、端口中有任何一个不同,就是跨域。

URL是否跨域原因
https://www.baidu.com/more/index.html不跨域三要素相同
https://map.baidu.com/跨域域名不同
http://www.baidu.com/index.html跨域协议不同
https://www.baidu.com:81/index.html跨域端口不同

# Filter

@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsFilter(urlBasedCorsConfigurationSource);
    }
}

# Configurer

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowCredentials(true)
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .maxAge(3600);
    }
}

# Controller

@RestController
@RequestMapping("/account")
public class AccountController {
    @CrossOrigin
    @GetMapping("/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }
    @DeleteMapping("/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

# 参数

  • origins :指定允许访问资源的源。可以是单个源或源列表。例如, https://example.com['https://example.com', 'https://api.example.com']
  • methods :指定允许的 HTTP 方法列表,用于访问资源。例如, GETPOSTPUT 等。默认情况下,只允许 GETHEADPOST 方法。
  • headers :指定允许的请求头列表,用于控制允许的自定义请求头。例如, Content-TypeAuthorization 等。默认情况下,只允许简单请求头。
  • exposedHeaders :指定允许客户端访问的响应头列表。例如, Content-LengthX-Custom-Header 等。默认情况下,只允许简单响应头。
  • credentials :指定是否允许发送凭据(如 cookies、HTTP 认证或客户端 SSL 证书)到服务器。可以是布尔值 truefalse 。默认情况下,不允许发送凭据。
  • maxAge :指定预检请求的有效期,以秒为单位。预检请求是浏览器在发送实际请求之前发送的一种 OPTIONS 请求,用于检查是否允许跨域访问。默认情况下,没有指定有效期。

# 失效

SpringMVC 版本大于 4.2 支持 @CrossOrigin。
@RequestMapping 注解中没有指定 Get、Post 方式。

@CrossOrigin
@RestController
public class person {
    @RequestMapping(method = RequestMethod.GET)
    public String add() {
        // 若干代码
    }
}
更新于