Spring-webmvc

CORS

2019-07-10  本文已影响0人  xzz4632

1. CORS

cross-origin resource sharing, 跨域资源共享.
因为出于安全的考虑, 浏览器不允许Ajax调用当前源之外的资源. 即浏览器的同源策略.
CORS需要浏览器和服务器同时支持。目前,所有主流浏览器都支持该功能,IE浏览器不能低于IE10。在浏览器端, 整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,用户对这些都不会有感觉。因此,实现CORS通信的关键是服务器。

2. 跨域请求分类

浏览器将跨域请求分为两大类: 简单请求和非简单请求.

同时满足以下条件的请求都为简单请求:

凡是同时满足以上两个条件的, 就是简单请求.

3. 跨域请求处理方式

3.1 简单请求

对于简单请求, 浏览器直接发出CORS请求, 即浏览器自动在请求header中加上Origin字段, 告诉服务器这个请求来自哪个源(请求协议+域名+端口). 服务器收到请求后, 会对比这个字段, 如果字段值不在服务器的许可范围内, 服务器会返回一个正常的HTTP响应, 但是其响应头中不会包含Access-Control-Allow-Origin字段, 浏览器发现后, 就会抛出一个异常提示响应头中没有这个字段. 如果这个源在服务器的许可范围内, 服务器的响应头会加上以下字段:

3.2 非简单请求

对于非简单请求, 浏览器的CORS请求分为两步, 首先是执行预检(preflight)请求, 询问服务器是否允许当前源访问, 如果允许, 才会执行实际请求, 预检请求可以缓存(缓存时间由服务器定义), 在缓存有效期内再执行CORS请求时无需进行预检请求.

3.2.1 预检请求

如果预检请求正常返回, 接下来执行实际请求. 在预检请求缓存有效期内, 再执行跨域请求时无需进行预检请求.

4. Spring跨域请求配置

4.1 @CrossOrigin

这个注解可以用于类上和方法上. 其属性有:

4.2 全局配置
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {

        registry.addMapping("/api/**")
            .allowedOrigins("https://domain2.com")
            .allowedMethods("PUT", "DELETE")
            .allowedHeaders("header1", "header2", "header3")
            .exposedHeaders("header1", "header2")
            .allowCredentials(true)
            .maxAge(3600);

        // Add more mappings... 可以添加多个mapping
    }
}
<mvc:cors>
    <mvc:mapping path="/api/**"
        allowed-origins="https://domain1.com, https://domain2.com"
        allowed-methods="GET, PUT"
        allowed-headers="header1, header2, header3"
        exposed-headers="header1, header2" allow-credentials="true"
        max-age="123" />

    <mvc:mapping path="/resources/**"
        allowed-origins="https://domain1.com" />
</mvc:cors>
4.3 CorsFilter

可以通过内置的CorsFilter应用CORS支持。如果使用带有Spring Security的CorsFilter,请记住Spring Security内置了对CORS的支持。

    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();

        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://localhost:8080");
        config.addAllowedHeader("os");
        config.addAllowedHeader("name");
        config.addAllowedHeader("addr");
        config.addAllowedMethod("*");
        config.addExposedHeader("name");
        config.setMaxAge(10L);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);

        CorsFilter filter = new CorsFilter(source);
        return filter;
    }
上一篇 下一篇

猜你喜欢

热点阅读