zoukankan      html  css  js  c++  java
  • CROS跨域请求处理

    1.什么是跨域?

      跨域是指从一个域名的网页去请求另一个域名的资源。比如从www.baidu.com 页面去请求 www.google.com 的资源。跨域的严格一点的定义是:只要 协议,域名,端口有任何一个的不同,就被当作是跨域

    2.为什么浏览器要限制跨域?

      原因就是安全问题:如果一个网页可以随意地访问另外一个网站的资源,那么就有可能在客户完全不知情的情况下出现安全问题。比如下面的操作就有安全问题:

    1. 用户访问www.mybank.com ,登陆并进行网银操作,这时cookie啥的都生成并存放在浏览器
    2. 用户突然想起件事,并迷迷糊糊地访问了一个邪恶的网站 www.xiee.com
    3. 这时该网站就可以在它的页面中,拿到银行的cookie,比如用户名,登陆token等,然后发起对www.mybank.com 的操作。
    4. 如果这时浏览器不予限制,并且银行也没有做响应的安全处理的话,那么用户的信息有可能就这么泄露了。

    3.为什么要跨域?

      既然有安全问题,那为什么又要跨域呢? 有时公司内部有多个不同的子域,比如一个是location.company.com ,而应用是放在app.company.com , 这时想从 app.company.com去访问 location.company.com 的资源就属于跨域。

    4.实现跨域需要的技术手段。

      1.JSONP或者CORS

    5.SpringMVC通过CORS实现跨域

      5.1定义一个Filter

    package cn.ucmed.baseline.d2d.api.filter;
    
    import org.springframework.web.filter.OncePerRequestFilter;
    
    import javax.servlet.FilterChain;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class CorsFilter extends OncePerRequestFilter {
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    
            if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) {
                // CORS "pre-flight" request
                response.addHeader("Access-Control-Allow-Origin", "*");
                response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
                response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
                response.addHeader("Access-Control-Max-Age", "1800");//30 min
            }
            //This will filter your requests and responses.
            filterChain.doFilter(request, response);
        }
    }

      5.2在web.xml中配置这个filter

    <filter>
        <filter-name>allowedAccessFilter</filter-name>
        <filter-class>cn.ucmed.baseline.d2d.api.filter.CorsFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>allowedAccessFilter</filter-name>
        <url-pattern>/registeryuyue/*</url-pattern>
    </filter-mapping>

    6.SpringBoot通过CORS实现跨域

    package cn.ucmed.otaku;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
    import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
    import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ImportResource;
    import org.springframework.web.cors.CorsConfiguration;
    import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
    import org.springframework.web.filter.CorsFilter;
    
    @EnableZuulProxy
    @SpringBootApplication(exclude = {
            DataSourceAutoConfiguration.class,
            HibernateJpaAutoConfiguration.class})
    @ImportResource("classpath*:META-INF/spring/dubbo.xml")
    public class GatewayApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(GatewayApplication.class, args);
        }
    
        @Bean
        public CorsFilter corsFilter() {
    
            final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            final CorsConfiguration config = new CorsConfiguration();
            config.setAllowCredentials(true);
            config.addAllowedOrigin("*");
            config.addAllowedHeader("*");
            config.addAllowedMethod("OPTIONS");
            config.addAllowedMethod("HEAD");
            config.addAllowedMethod("GET");
            config.addAllowedMethod("PUT");
            config.addAllowedMethod("POST");
            config.addAllowedMethod("DELETE");
            config.addAllowedMethod("PATCH");
            config.addExposedHeader("token");
            source.registerCorsConfiguration("/**", config);
            return new CorsFilter(source);
        }
    }

    7.jquery $.ajax()跨域请求获取heads。

      ajax通过xhr.getAllResponseHeaders()能得到所有response headers,通过xhr.getResponseHeader('token')能获取到具体的head值,but,ajax跨域的请求getAllResponseHeaders()却怎么也获取不到全部的head值,只能获取到content-type这个head值,在http://stackoverflow.com/questions/15042439/cant-get-custom-http-header-response-from-ajax-getallresponseheaders终于找到了答案。需要在服务器端加 'Access-Control-Expose-Headers: header1,header2,header3'才能获取到header1,header2,header3

      $.ajax({
                type: "get",
                url: urlStr, //跨域的域名
                data: transmitModel,
                headers: {
                    notice_str: randomStr,
                    timestamp: timestamp,
                    sign: signStr
                },
                success: function(data, status, xhr) {
                    console.info(xhr.getAllResponseHeaders());
                    console.info(xhr.getResponseHeader('token'))
                    console.info(data);
                    console.info(status);
                },
                error: function(e) {
                    
                },
                complete: function() {
                    
                }
    
            });

    SpringMVC的Filter

    public class CorsFilter extends OncePerRequestFilter {
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    
            if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) {
                // CORS "pre-flight" request
                response.addHeader("Access-Control-Allow-Origin", "*");
                response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
                response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
                response.addHeader("Access-Control-Max-Age", "1800");//30 min
                response.addHeader("Access-Control-Expose-Headers", "token");
            }
            //This will filter your requests and responses.
            filterChain.doFilter(request, response);
        }
    }

    SpringBoot的bean

      @Bean
        public CorsFilter corsFilter() {
    
            final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            final CorsConfiguration config = new CorsConfiguration();
            config.setAllowCredentials(true);
            config.addAllowedOrigin("*");
            config.addAllowedHeader("*");
            config.addAllowedMethod("OPTIONS");
            config.addAllowedMethod("HEAD");
            config.addAllowedMethod("GET");
            config.addAllowedMethod("PUT");
            config.addAllowedMethod("POST");
            config.addAllowedMethod("DELETE");
            config.addAllowedMethod("PATCH");
            config.addExposedHeader("token");
            source.registerCorsConfiguration("/**", config);
            return new CorsFilter(source);
        }

    参考:

    [1]博客,http://www.ruanyifeng.com/blog/2016/04/cors.html,跨资源共享CROS详解

    [2]博客,http://blog.csdn.net/notechsolution/article/details/50394391,跨域与跨域访问

    [3]博客,https://www.cnblogs.com/wwlhome/p/5787133.html,$.ajax应用之请求头headers

    [4]博客,http://www.qdfuns.com/notes/17001/6df913ad0788f32e6908d70c849b7b8e.html,如何获取跨域请求的自定义response headers

  • 相关阅读:
    Eclipse中用两个控制台测试网络通信程序
    c++ primer 11 泛型算法
    c++ primer 10 关联容器
    c++ primer 9 顺序容器
    c++ primer 8 标准IO库
    安装使用
    InfluxDB介绍
    proxy.go
    monitor.go
    balancer.go
  • 原文地址:https://www.cnblogs.com/happyflyingpig/p/8118818.html
Copyright © 2011-2022 走看看