Spring Boot对Ajax跨域访问的支持实现

Spring Boot对Ajax跨域访问的支持实现

作者在SE305课程中,需要设计一款新时代互联网购票系统,团队使用vue.js前端,Spring MVC的后台架构。开发过程中遇到跨域访问的问题,故写成此博客进行探讨解决方案。主要涉及的话题有:

  • Spring Boot
  • AJAX
  • 跨域访问

问题定义

究竟什么是跨域访问?作者引用了MDN对CORS的定义https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

当一个资源从与该资源本身所在的服务器的域或端口不同的域或不同的端口请求一个资源时,资源会发起一个跨域 HTTP 请求。
比如,站点 http://domain-a.com 的某 HTML 页面通过 的 src 请求
http://domain-b.com/image.jpg。网络上的许多页面都会加载来自不同域的CSS样式表,图像和脚本等资源。
出于安全考虑,浏览器会限制从脚本内发起的跨域HTTP请求。例如,XMLHttpRequest 和 Fetch 遵循同源策略。因此,使用
XMLHttpRequest或 Fetch
的Web应用程序只能将HTTP请求发送到其自己的域。为了改进Web应用程序,开发人员要求浏览器厂商允许跨域请求。

下面是简单的流程图:
流程图

根本解决思路

客户端和服务器之间使用 CORS 首部字段来处理跨域权限:
交互图
也就是说在HTTP request以及response加入CORS对应的首部行字段即可解决。下面讲解在spring下的后台解决方案

实现方案

方案一

在Controller类或其方法上加@CrossOrigin注解

@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping("/Cinema")
public class CinemaController {
//Cinema控制器,跨域来源为*即任何来源
}

方案二

在web.xml中配置一个CorsFilter

<filter-mapping>
    <filter-name>CorsFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

而filter的实现如下

@Component
public class InitCORSFilter extends OncePerRequestFilter {

    private Logger logger = LoggerFactory.getLogger(InitCORSFilter.class);

    public InitCORSFilter() {

    }

    //表示服务器端允许任意Domain访问请求

    @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())) {
            response.addHeader("Access-Control-Allow-Origin", "*");
            response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
            response.addHeader("Access-Control-Allow-Headers", "origin, content-type, accept, x-requested-with, sid, mycustom, smuser");
            response.addHeader("Access-Control-Max-Age", "600");    //Max age为10mins
        }
        filterChain.doFilter(request, response);
    }

}

方案三(本次项目使用的方法)

本次项目使用spring-boot,可以把CorsFilter作为@Bean加入到@Configuration中即可配置,方便简洁。

@Configuration
public class CorsConfig {
    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig()); 
        return new CorsFilter(source);
    }
}//通过任意请求

总结

解决的不二思路就是当捕获到Cors请求(使用Filter实现)时,返回包含特定Header的Response。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值