zoukankan      html  css  js  c++  java
  • 关于Spring MVC跨域

    1.Sping MVC 3.X跨域

    关于跨域问题,主要用的比较多的是cros跨域。
     
    但是,在springmvc+angularjs下支持跨域请求时,出现复杂跨域场景(post + json)失败的情况。
    开始的跨域配置如下:
    public class CrossInterceptor extends HandlerInterceptorAdapter {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            response.addHeader("Access-Control-Allow-Origin","*");
            response.addHeader("Access-Control-Allow-Methods","*");
            response.addHeader("Access-Control-Max-Age","100");
            response.addHeader("Access-Control-Allow-Headers", "Content-Type");
            response.addHeader("Access-Control-Allow-Credentials","false");
            return super.preHandle(request, response, handler);
        }
    
    }
    spring-dispatcher-servlet.xml中配置如下:
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**/*"/>
            <bean class="cn.***.filter.CrossInterceptor" />
        </mvc:interceptor>
    </mvc:interceptors>
    针对简单跨域没问题。但是针对post+json请求却失败,提示跨域失败。
    跟踪springmvc源码到FrameworkServlet中的doOption方法,发现,接受了option预检,但是spring主动返回allow,没有支持跨域的配置。
    因此,加入新的配置如下:
    public class CrossFilter 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");
                response.addHeader("Access-Control-Allow-Headers", "Content-Type");
                response.addHeader("Access-Control-Max-Age", "1800");//30 min
            }
            filterChain.doFilter(request, response);
        }
    }

    web.xml配置如下:
    <filter>
        <filter-name>cors</filter-name>
        <filter-class>cn.***.filter.CrossFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>cors</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
     
     
    此时,option请求被CrossFilter过滤器接入并赋予跨域响应头,同时也进入FrameworkServlet中的doOption方法。查看浏览器控制台,发现option请求返回支持跨域信息,后续的post请求进入controller。
     

    2.Sping MVC 4.X跨域

    升级spring版本的后,上述跨域并不支持所有浏览器。经测试,Safari正常,chrome异常。重新翻了一下最新的文档后,得到最新的跨域配置如下:

        <mvc:cors>
            <mvc:mapping path="/**" allowed-origins="*" allow-credentials="true" max-age="1800" allowed-methods="GET,POST,OPTIONS"/>
        </mvc:cors>

    相比3.x系列,简单了很多。

    3.过滤器响应头常用的设置

                response.setHeader("Access-Control-Allow-Origin", "*");  
                response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE,PUT");  
                response.setHeader("Access-Control-Max-Age", "3600");  
                response.setHeader("Access-Control-Allow-Headers","appKey,token,Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since");  
                response.setHeader("Access-Control-Allow-Credentials", "true");
                /* 设置响应头为Json */
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json");

    ----转自:http://www.cnblogs.com/asfeixue/p/4363372.html

     
  • 相关阅读:
    两个页面相同js方法兼容
    两个页面js方法兼容
    jQuery Chosen 使用
    我写的一个抓取基金净值的工具
    自己做的一个固定大小对象内存池,效率大概为原始的new/delete的2倍
    用libevent实现的echo服务器及telnet客户端
    共享一个防止脚本重复启动的shell脚本
    神煞排盘软件
    一个在字符串中查找多个关键字的函数strstrs(三种不同算法实现及效率分析)
    写了一个时间处理的类,能将人类时间转换成距离公元零年一月一日秒数(时间戳),同时支持时间戳转换成日期时间
  • 原文地址:https://www.cnblogs.com/zf29506564/p/7146936.html
Copyright © 2011-2022 走看看