zoukankan      html  css  js  c++  java
  • springMVC解决跨域

    原文:https://www.cnblogs.com/shihaiming/p/9544060.html

    介绍:   跨站 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,这些浏览器在请求还未发出的时候就会拦截请求,这是一个特例。

    同源:指的是域名(或IP)协议端口都相同,不同源的客户端脚本(javascript、ActionScript)在没明确授权的情况下,不能读写对方的资源。

    URL解释是否跨域
    http://www.morethink.cn 原来的URL  
    http://www.image.morethink.cn 子域名 跨域(cookie也无法访问)
    http://morethink.cn 不加www 跨域
    https://www.morethink.cn 更改协议 跨域
    http://www.morethink.cn:8080 更改端口号 跨域

    模拟第三方调取:

    var xhr = new XMLHttpRequest();
    xhr.open('POST', 'http://localhost:8080/agentwap/auth/toTransfer.do?callbackAddress=https://www.baidu.com',true);
    xhr.send();
    xhr.onreadystatechange=function() {
    if(xhr.readyState == 4) {
    if(xhr.status == 200) {
    console.log(JSON.parse(xhr.responseText));
    }
    }
    }

    解决方案:

    普通参数跨域

    在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>
  • 相关阅读:
    NSURLSession学习笔记(一)简介
    Objective-C的属性和成员变量用法及关系浅析
    Object-C 中的Selector 概念
    IOS SEL (@selector) 原理及使用总结(一)
    iOS应用截屏
    iOS运行时工具-cycript
    iOS设备是否越狱的判断代码
    iphone——日期处理
    在iOS中使用ZBar扫描二维码
    使用Dockerfile docker tomcat部署
  • 原文地址:https://www.cnblogs.com/chuang-sharing/p/12067293.html
Copyright © 2011-2022 走看看