※跨域※

注解@CrossOrigin解决跨域问题:Spring Framework 4.2 GA为CORS提供了第一类支持,使您比通常的基于过滤器的解决方案更容易和更强大地配置它。所以springMVC的版本要在4.2或以上版本才支持@CrossOrigin

♬参考链接:https://www.cnblogs.com/mmzs/p/9167743.html

package cn.itcast.haoke.dubbo.api.controller;

import cn.itcast.haoke.dubbo.api.config.MockConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RequestMapping("mock")
@RestController
@CrossOrigin

public class MockController {

    @Autowired
    private MockConfig mockConfig;

    /*菜单*/
    @GetMapping("index/menu")
    public String indexMenu() {
        return this.mockConfig.getIndexMenu();
    }

    /*首页资讯*/
    @GetMapping("index/info")
    public String indexInfo() {
        return this.mockConfig.getIndexInfo();
    }

    /**
     *   * 首页问答
     *   * @return
     *   
     */
    @GetMapping("index/faq")
    public String indexFaq() {
        return this.mockConfig.getIndexFaq();
    }

}

  ※基于WebMVC实现跨域:

//增加CORS的支持
//整合前端系统测试会发现,前面实现的拦截器中并没有对跨域进行支持,需要对CORS跨域支持:
@Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse
response, Object handler) throws Exception {
    if(StringUtils.equalsIgnoreCase(request.getMethod(), "OPTIONS")){
      return true;
   }
   
    if (!StringUtils.equalsIgnoreCase(request.getMethod(), "get")) {
      // 非get请求,如果不是graphql请求,放行
      if (!StringUtils.equalsIgnoreCase(request.getRequestURI(), "/graphql"))
{
        return true;
     }
   }
    String data =
this.redisTemplate.opsForValue().get(createRedisKey(request));
    if (StringUtils.isEmpty(data)) {
      // 缓存未命中
      return true;
   }
    response.setCharacterEncoding("UTF-8");
    response.setContentType("application/json; charset=utf-8");
    // 支持跨域
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods",
"GET,POST,PUT,DELETE,OPTIONS");
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type,X-Token");
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.getWriter().write(data);
    return false;
 }

  

Spring Boot 中如何解决跨域问题 ?
跨域可以在前端通过 JSONP 来解决,但是 JSONP 只可以发送 GET 请求,无法发送其他类型的请求,在 RESTful 风格的应用中,就显得非常鸡肋,因此我们推荐在后端通过 (CORS,Cross-origin resource sharing) 来解决跨域问题。这种解决方案并非 Spring Boot 特有的,在传统的 SSM 框架中,就可以通过 CORS 来解决跨域问题,只不过之前我们是在 XML 文件中配置 CORS ,现在可以通过实现WebMvcConfigurer接口然后重写addCorsMappings方法解决跨域问题。

@Configuration
public class CorsConfig implements WebMvcConfigurer {

@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.maxAge(3600);
}

}

项目中前后端分离部署,所以需要解决跨域的问题。
我们使用cookie存放用户登录的信息,在spring拦截器进行权限控制,当权限不符合时,直接返回给用户固定的json结果。
当用户登录以后,正常使用;当用户退出登录状态时或者token过期时,由于拦截器和跨域的顺序有问题,出现了跨域的现象。
我们知道一个http请求,先走filter,到达servlet后才进行拦截器的处理,如果我们把cors放在filter里,就可以优先于权限拦截器执行。

@Configuration
public class CorsConfig {

@Bean
public CorsFilter corsFilter() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(urlBasedCorsConfigurationSource);
}

}

posted @ 2020-01-17 12:17  酌醉  阅读(121)  评论(0编辑  收藏  举报