SpringBoot 解决跨域问题

2019-01-28  本文已影响13人  东方不喵

在项目开发中,时常会遇到跨域问题,常用的方法有3种:
1.jsonp ; 2. 过滤器拦截请求头 ; 3.服务器代理 。

1. Jsonp

jsonp的原理是: 将json数据包裹成为js,再与前端进行通信。而前端通过解析js,来获取数据。
在Spring项目中,已经提供了很快捷的方式集成这种返回开发。

package com.hrh.modules.ajax.controllers.handles;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.AbstractJsonpResponseBodyAdvice;

/**
 * SpringBoot 使用Jsonp
 * @author  ren
 * @date 2018/6/4
 */
@ControllerAdvice
public class AjaxAdvice extends AbstractJsonpResponseBodyAdvice {

    public AjaxAdvice(){
        super("callback");
    }

}

2. 拦截器方式

出现跨域问题主要是前端解析 xhr请求时候,请求头解析的问题。
在头中添加 res.addHeader("Access-Control-Allow-Origin",origin);,来进行动态配置。

package com.hrh.modules.ajax.controllers.handles;

import org.springframework.util.StringUtils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author ren
 * @date 2018/6/5
 */
public class CrosFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse res = (HttpServletResponse) servletResponse;

        /**
         *  允许指定请求头跨域
         */
//        res.addHeader("Access-Control-Allow-Origin","http://localhost:8083");
//        res.addHeader("Access-Control-Allow-Methods","GET");

        /**
         *  允许简单请求:
         *  方法为:GET,HEAD,POST
         *  请求header里面
         *      无自定义头
         *      Content-Type 为以下几种:
         *          text/plain
         *          multipart/form-data
         *          application/x-www-form-urlencoded
         *   ‘ * ’不支持cookie
         */
//        res.addHeader("Access-Control-Allow-Origin","*");
//        res.addHeader("Access-Control-Allow-Methods","*");

        /**
         *  非简单请求
         *      put,delete方法的ajax请求
         *      发送json格式的ajax请求
         *      带自定义头的ajax请求
         *      满足带Cookie请求
         */
       String origin =  req.getHeader("Origin");
       if(!StringUtils.isEmpty(origin)){
           res.addHeader("Access-Control-Allow-Origin",origin);
       }
        res.addHeader("Access-Control-Allow-Methods","*");

        // Post 解析
        String headers =  req.getHeader("Access-Control-Request-Headers");
        if(!StringUtils.isEmpty(headers)){
            res.addHeader("Access-Control-Request-Headers",headers);
        }

        // 预解命令缓存
        res.addHeader("Access-Control-Max-Age","3600");

        // enable cookie
        res.addHeader("Access-Control-Allow-Credentials","true");

        filterChain.doFilter(req,res);
    }

    @Override
    public void destroy() {

    }
}

创建完成过滤器之后,需要注入号Servlet容器中。
SpringBoot注入Filter方式。可以配置路径

package com.hrh.modules.ajax.configs;

import com.hrh.modules.ajax.controllers.handles.CrosFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author ren
 * @date 2018/7/24
 */
@Configuration
public class AjaxConfiguration {

    @Bean
    public FilterRegistrationBean registerFilter(){

        FilterRegistrationBean bean = new FilterRegistrationBean();

        bean.addUrlPatterns("/*");
        bean.setFilter(new CrosFilter());

        return bean;
    }

}
上一篇下一篇

猜你喜欢

热点阅读