Spring是如何实现跨域的几种方式?

1.同源策略

所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)

2.什么是跨域

既然都知道什么是同源策略,那说穿了,只要协议,主机,端口号有一个不同就跨域呗。

image.png

3.后端实现跨域的几种方法

不要问我为什么没有nignx,因为写过了,这几种,我都没用过,就当了解,不是,正常人会用这几种吗?

  1. 返回新的CorsFilter

  2. 重写 WebMvcConfigurer

  3. 使用注解 @CrossOrigin

  4. 手动设置响应头 (HttpServletResponse)

  5. 自定web filter 实现跨域
    注意:

  • CorFilter / WebMvConfigurer / @CrossOriginspringBoot 1.3以后才支持的。
  • 上面前两种方式属于全局 CORS 配置,后两种属于局部 CORS配置。如果使用了局部跨域是会覆盖全局跨域。正常人都用局部跨域吧?
  • 其实无论哪种方案,最终目的都是修改响应头,向响应头中添加浏览器所要求的数据,进而实现跨域。

4.返回新的 CorsFilter(全局跨域)(基于过滤器)

CorsFilter 是 Spring 框架提供的一个用于处理跨域的过滤器,注意了,人家是属于spring的,不是JDK的,不要瞎搞关系

// 原CORSFilter
@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter  corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        // 允许cookies跨域
        config.setAllowCredentials(true); 
        // #允许向该服务器提交请求的URI,*表示全部允许,自定义可以添加多个,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin
        config.addAllowedOrigin("*");
        // #允许访问的头信息,*表示全部,可以添加多个
        config.addAllowedHeader("*");
        // 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了
        config.setMaxAge(1800L);
        // 允许提交请求的方法,*表示全部允许,一般OPTIONS,GET,POST三个够了
        config.addAllowedMethod("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        //对所有接口都有效
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

5重写 WebMvcConfigurer我们现在需要对请求路径进行拦截,要实现这个需求就要添加拦截器(基于拦截器)

在Spring Boot 1.5版本都是靠重写WebMvcConfigurerAdapter的方法来添加自定义拦截器,消息转换器等。SpringBoot 2.0 后,该类被标记为@Deprecated(弃用)

建议重点看看这篇博客

跨域解决之CorsFilter与WebMvcConfigurer篇_corsconfigurer_雪莉酒的博客-CSDN博客

总结一波:** 拦截器会让WebMvcConfigurer全局跨域配置失效,这种情况下可以使用过滤器进行跨域处理**

6使用注解 @CrossOrigin

在控制器(类上)上使用注解 @CrossOrigin:表示该类的所有方法允许跨域
在方法上使用注解 @CrossOrigin:

原理:当我们使用@CrossOrigin注解时,程序在底层添加了一个拦截器来修改response的headers属性,从而解决跨域问题

image.png

7手动设置响应头 (HttpServletResponse)

@RequestMapping("/index")
public String index(HttpServletResponse response) {
    response.addHeader("Access-Allow-Control-Origin","*");
    return "index";
}

有点抖机灵

8自定web filter 实现跨域

package com.mesnac.aop;
 
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
@Component
public class MyCorsFilter implements Filter {
  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    HttpServletResponse response = (HttpServletResponse) res;
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");
    chain.doFilter(req, res);
  }
  public void init(FilterConfig filterConfig) {}
  public void destroy() {}
}

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYsm5ZE8' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片