zoukankan      html  css  js  c++  java
  • Spring MVC学习总结(10)——Spring MVC使用Cors跨域

        跨站 HTTP 请求(Cross-site HTTP request)是指发起请求的资源所在域不同于该请求所指向资源所在的域的 HTTP 请求。比如说,域名A(http://domaina.example)的某 Web 应用程序中通过标签引入了域名B(http://domainb.foo)站点的某图片资源(http://domainb.foo/image.jpg),域名A的那 Web 应用就会导致浏览器发起一个跨站 HTTP 请求。在当今的 Web 开发中,使用跨站 HTTP 请求加载各类资源(包括CSS、图片、JavaScript 脚本以及其它类资源),已经成为了一种普遍且流行的方式。正如大家所知,出于安全考虑,浏览器会限制脚本中发起的跨站请求。比如,使用 XMLHttpRequest 对象发起 HTTP 请求就必须遵守同源策略(same-origin policy)。 具体而言,Web 应用程序能且只能使用 XMLHttpRequest 对象向其加载的源域名发起 HTTP 请求,而不能向任何其它域名发起请求。为了能开发出更强大、更丰富、更安全的Web应用程序,开发人员渴望着在不丢失安全的前提下,Web 应用技术能越来越强大、越来越丰富。比如,可以使用 XMLHttpRequest 发起跨站 HTTP 请求。(这段描述跨域不准确,跨域并非浏览器限制了发起跨站请求,而是跨站请求可以正常发起,但是返回结果被浏览器拦截了。最好的例子是crsf跨站攻击原理,请求是发送到了后端服务器无论是否跨域!注意:有些浏览器不允许从HTTPS的域跨域访问HTTP,比如Chrome和Firefox,这些浏览器在请求还未发出的时候就会拦截请求,这是一个特例。)

    普通参数跨域

    在response的头文件添加

    httpServletResponse.setHeader("Access-Control-Allow-Origin","*");
    httpServletResponse.setHeader("Access-Control-Allow-Methods","POST");
    httpServletResponse.setHeader("Access-Control-Allow-Headers","Access-Control");
    httpServletResponse.setHeader("Allow","POST");
    
    Access-Control-Allow-Origin:| * // 授权的源控制
    Access-Control-Max-Age:// 授权的时间
    Access-Control-Allow-Credentials: true | false // 控制是否开启与Ajax的Cookie提交方式
    Access-Control-Allow-Methods:[,]* // 允许请求的HTTP Method
    Access-Control-Allow-Headers:[,]* // 控制哪些header能发送真正的请求  

    观察响应头

    带headr请求跨域

       这样客户端需要发起 OPTIONS请求, 可以说是一个“预请求”,用于探测后续真正需要发起的跨域 POST 请求对于服务器来说是否是安全可接受的,因为跨域提交数据对于服务器来说可能存在很大的安全问题。

    因为Springmvc模式是挂壁OPTIONS请求的,所以需要开启

    <servlet>    
       <servlet-name>application</servlet-name>    
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
       <init-param>  
            <param-name>dispatchOptionsRequest</param-name>  
            <param-value>true</param-value>  
       </init-param>    
       <load-on-startup>1</load-on-startup>    
    </servlet>    

     

    Spring MVC 从4.2版本开始增加了对CORS的支持

    spring MVC 中增加CORS支持非常简单,可以配置全局的规则,也可以使用@CrossOrigin注解进行细粒度的配置。

    使用@CrossOrigin注解

    先通过源码看看该注解支持的属性:

    在Controller上使用@CrossOrigin注解

    @CrossOrigin(origins = "*", maxAge = 3600)
    @RestController
    @RequestMapping("/account")
    public class AccountController {
    
        @RequestMapping("/{id}")
        public Account retrieve(@PathVariable Long id) {
            // ...
        }
    
        @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
        public void remove(@PathVariable Long id) {
            // ...
        }
    }

    这里指定当前的AccountController中所有的方法可以处理所有域上的请求,

    在方法上使用@CrossOrigin注解

    @CrossOrigin(maxAge = 3600)
    @RestController
    @RequestMapping("/account")
    public class AccountController {
    
        @CrossOrigin("http://domain2.com")
        @RequestMapping("/{id}")
        public Account retrieve(@PathVariable Long id) {
            // ...
        }
    
        @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
        public void remove(@PathVariable Long id) {
            // ...
        }
    }

    在这个例子中,AccountController类上也有@CrossOrigin注解,retrieve方法上也有注解,Spring会合并两个注解的属性一起使用。

    CORS全局配置

    除了细粒度基于注解的配置,你可能会想定义一些全局CORS的配置。这类似于使用过滤器,但可以在Spring MVC中声明,并结合细粒度@CrossOrigin配置。默认情况下所有的域名和GET、HEAD和POST方法都是允许的。

    基于JAVA的配置

    看下面例子:

    @Configuration
    public class WebConfig extends WebMvcConfigurerAdapter {
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**");
        }
    }

    您可以轻松地更改任何属性,以及配置适用于特定的路径模式的CORS:

    如果你使用Spring Boot,你可以通过这种方式方便的进行配置。

    @Configuration
    public class WebConfig extends WebMvcConfigurerAdapter {
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/api/**")
                .allowedOrigins("http://domain2.com")
                .allowedMethods("PUT", "DELETE")
                .allowedHeaders("header1", "header2", "header3")
                .exposedHeaders("header1", "header2")
                .allowCredentials(false).maxAge(3600);
        }
    }

    不限制任何请求(方便复制粘贴)

    @Configuration
    public class CorsConfig extends WebMvcConfigurerAdapter {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins("*")
                    .allowedMethods("GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "TRACE");
        }
    }

    基于XML的配置

    <mvc:cors><mvc:mapping path="/**" />
    </mvc:cors>

    这个配置和上面Java方式的第一种作用一样。

    同样,你可以做更复杂的配置:

    <mvc:cors><mvc:mapping path="/api/**"
            allowed-origins="http://domain1.com, http://domain2.com"
            allowed-methods="GET, PUT"
            allowed-headers="header1, header2, header3"
            exposed-headers="header1, header2" allow-credentials="false"
            max-age="123" /><mvc:mapping path="/resources/**"
            allowed-origins="http://domain1.com" /></mvc:cors>
  • 相关阅读:
    mysql修改数据表名
    HDU 5742 It's All In The Mind (贪心)
    HDU 5752 Sqrt Bo (数论)
    HDU 5753 Permutation Bo (推导 or 打表找规律)
    HDU 5762 Teacher Bo (暴力)
    HDU 5754 Life Winner Bo (博弈)
    CodeForces 455C Civilization (并查集+树的直径)
    CodeForces 455B A Lot of Games (博弈论)
    CodeForces 455A Boredom (DP)
    HDU 4861 Couple doubi (数论 or 打表找规律)
  • 原文地址:https://www.cnblogs.com/zhanghaiyang/p/7212760.html
Copyright © 2011-2022 走看看