写在前面

跨域问题并不是spring特有的,本文简要的介绍跨域问题的来龙去脉,以及 spring处理跨域问题的两种方式。

1. 什么导致了跨域

浏览器的同源策略导致了跨域问题。

1.1 同源策略

同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。

同源的定义:如果两个页面的协议,端口和主机都相同,则两个页面具有相同的源。

1.2 跨源访问

使用 CORS 允许跨源访问。

CORS 的工作原理是: 添加新的HTTP标头,让服务器描述允许哪些来源从Web浏览器读取该信息

2. Spring MVC 的跨域问题

服务器不做任何跨域配置时,通过 ajax 从前端页面 localhost:8080 请求 localhost:8081 时:

springmvc post请求跨域_spring


并且控制台会报如下错误:

springmvc post请求跨域_spring_02

如果你仔细阅读了前面所给出的博客以后,会很容易理解为什么会出现上面的问题。

那么 spring 如何解决跨域问题呢?我所找到能够通过以下两种方法来处理:

  1. CrossOrigin 注解
  2. CorsConfiguration
2.1 CrossOrigin注解

该注解可以作用在类以及方法层面上,当作用在类(Controller)层面上时,该类下的所有路径均允许跨域访问;当作用在方法层面上时,只有当前方法对应的路径允许跨域访问。

当将注解的 origins 的值设置为 “ http://localhost:8082 ”时(我们实际的origin 为 http://localhost:8080),访问会返回 403 状态码 ,这是个有趣的现象;这应该表明了允许跨域,但你并不是允许的源。

2.2 CorsConfiguration

该类需要在 spring mvc 配置类中使用:

@Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        //设置允许跨域的路径
        registry.addMapping("/**")
                //设置允许跨域请求的域名
                .allowedOrigins("*")
                //是否允许证书 不再默认开启
                .allowCredentials(true)
                //设置允许的方法
                .allowedMethods("*")
                //跨域允许时间
                .maxAge(3600);
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new StringHttpMessageConverter());
        converters.add(new MappingJackson2HttpMessageConverter());
    }
}

或者更高级的配置类:

@Configuration
public class AdvancedWebMvcConfig extends WebMvcConfigurationSupport {

    @Override
    protected void addCorsMappings(CorsRegistry registry) {
        super.addCorsMappings(registry);
        //设置允许跨域的路径
        registry.addMapping("/**")
                //设置允许跨域请求的域名
                .allowedOrigins("*")
                //是否允许证书 不再默认开启
                .allowCredentials(true)
                //设置允许的方法
                .allowedMethods("*")
                //跨域允许时间
                .maxAge(3600);
    }
}