• springmvc中跨域问题


    对于web框架中的跨域问题是一个非常普遍的问题,常见的解决方案也有很多,如:jsonp、cros、websocket等。下面是最近处理springmvc中使用cors解决跨域问题的一些总结。

    Filter

    具体实现不在详细描述,基本原理利用filter拦截到所有请求,然后进行跨域设置。

    拦截器

    • 实现代码

      public class WeCrosInterceptor implements HandlerInterceptor {
          public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
              if (request.getHeader(HttpHeaders.ORIGIN) != null) {
                  response.addHeader("Access-Control-Allow-Origin", "*");
                  response.addHeader("Access-Control-Allow-Credentials", "true");
                  response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT, HEAD");
                  response.addHeader("Access-Control-Allow-Headers", "Content-Type");
                  response.addHeader("Access-Control-Max-Age", "3600");
              }
              return true;
          }
      
          public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
          }
      
          public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
          }
      }
      
    • 配置

      <mvc:interceptors>
          <mvc:interceptor>
              <mvc:mapping path="/**/*"/>
              <bean class="com.***.interceptor.WeCrosInterceptor" />
          </mvc:interceptor>
      </mvc:interceptors>
      

    注意:如果系统中有其他拦截器,要将该拦截器放在第一个。

    springmvc4.2之后版本

    @CrossOrigin注解

    可注解在方法上,也可注解在类上

    • 示例

      @CrossOrigin(origins = "http://www.zhihu.com")
      @RequestMapping(value = "/allProductions", method = RequestMethod.GET)
      public Result getAllOldProductions() {
      
      }
      

    xml全局配置

    • 所有跨域请求都可以访问

      <mvc:cors>
          <mvc:mapping path="/**" />
      </mvc:cors>
      
    • 细粒度的配置

      <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>
      

    以上两种方式在正常使用<mvc:annotation-driven 加载情况下完全可以满足需求。

    特殊情况下跨域问题

    如果重写了RequestMappingHandlerMapping,就需要单独配置,此时会发现全局的xml配置没有作用了,具体原因是没有使用springmvc框架解析的跨域配置最终是注入给RequestMappingHandlerMapping这个类的对象的,重写后的mapping对象不会被注入,怎么解决这个问题呢?filter 
    、拦截器都可以解决,但是都用了4.2的版本还要额外配置是不是太low了,经过查看源码,发现AbstractHandlerMapping有个setCorsConfigurations方法是用来设置跨域配置的,下面最终配置:

    <bean name='handlerMapping' class="com.we.core.web.view.WeRequestMappingHandlerMapping">
        <property name="corsConfigurations">
            <map>
                <entry key="/**">
                    <bean class="org.springframework.web.cors.CorsConfiguration">
                        <property name="allowedMethods" value="GET,POST,OPTIONS"/>
                        <property name="allowedOrigins" value="*"/>
                        <property name="allowedHeaders" value="*"/>
                        <property name="allowCredentials" value="true"/>
                        <property name="maxAge" value="1800"/>
                    </bean>
                </entry>
            </map>
        </property>
    </bean>
    

    无需增加多余配置类,完美解决问题。

  • 相关阅读:
    【c++】流状态的查询和控制
    【c++】iostreeam中的类为何不可以直接定义一个无参对象呢
    异步操作超出页面超时时间
    sql转Linq的工具
    用离职换来的领悟:人生没有最佳时机
    Log4Net日志记录两种方式
    C# FileStream复制大文件
    C#常用的集合类型(ArrayList类、Stack类、Queue类、Hashtable类、SortedList类)
    C# 读取 timestamp 时间戳 值为byte[] 类型时转换为时间戳字符串
    IIS7错误:“Web服务器被配置为不列出此目录的内容”的解决办法
  • 原文地址:https://www.cnblogs.com/f-anything/p/8707518.html
Copyright © 2020-2023  润新知