SpringMVC cors配置

目前跨域有2种解决方案

 

1、jsonp:这种方式比较古老。 需要前后端配合 这里就不多说了 。 好处就是兼容老的浏览器

2、cors:这种方式是目前的主流。 CORS就是。。什么什么共享。 原理呢。就是服务器在response里面配置上各种允许。就好了。 

cors又分2种

网上资料很多。我这里简单概述一下

1、简单请求:平常get、post(表单提交) 啥头信息都不加的情况 就是简单请求

2、复杂请求:如:post 传递 json形式的data 就是复杂请求

 

一、自定义Filter

 

之前api项目一直使用CorsFilter 。原理其实就是

写一个Filter在response中增加各种允许。 允许什么域名来访问,允许什么头信息之类的

 

public class CorsFilter implements Filter {  
  
    private String allowOrigin;  
    private String allowMethods;  
    private String allowCredentials;  
    private String allowHeaders;  
    private String exposeHeaders;  
  
    @Override  
    public void init(FilterConfig filterConfig) throws ServletException {  
        allowOrigin = filterConfig.getInitParameter("allowOrigin");  
        allowMethods = filterConfig.getInitParameter("allowMethods");  
        allowCredentials = filterConfig.getInitParameter("allowCredentials");  
        allowHeaders = filterConfig.getInitParameter("allowHeaders");  
        exposeHeaders = filterConfig.getInitParameter("exposeHeaders");  
        System.out.println("allowOrigin = " + allowOrigin);
        System.out.println("allowMethods = " + allowMethods);
        System.out.println("allowCredentials = " + allowCredentials);
        System.out.println("allowHeaders = " + allowHeaders);
        System.out.println("exposeHeaders = " + exposeHeaders);
    }  
  
    @Override  
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {  
        HttpServletRequest request = (HttpServletRequest) req;  
        HttpServletResponse response = (HttpServletResponse) res;  
        if (StringUtil.isNotEmpty(allowOrigin)) {  
            List<String> allowOriginList = Arrays.asList(allowOrigin.split(","));  
            if (allowOriginList != null && allowOriginList.size() > 0) {  
                String currentOrigin = request.getHeader("Origin");  
                if (allowOriginList.contains(currentOrigin)) {  
                    response.setHeader("Access-Control-Allow-Origin", currentOrigin);  
                }  
            }  
        }  
        if (StringUtil.isNotEmpty(allowMethods)) {  
            response.setHeader("Access-Control-Allow-Methods", allowMethods);  
        }  
        if (StringUtil.isNotEmpty(allowCredentials)) {  
            response.setHeader("Access-Control-Allow-Credentials", allowCredentials);  
        }  
        if (StringUtil.isNotEmpty(allowHeaders)) {  
            response.setHeader("Access-Control-Allow-Headers", allowHeaders);  
        }  
        if (StringUtil.isNotEmpty(exposeHeaders)) {  
            response.setHeader("Access-Control-Expose-Headers", exposeHeaders);  
        }  
        chain.doFilter(req, res);  
    }  
  
    @Override  
    public void destroy() {  
    }  
}  
<filter>
		<filter-name>corsFilter</filter-name>
		<filter-class>com.yunxin.iambuyer.ucenter.filter.CorsFilter</filter-class>
		<init-param>
			<param-name>allowOrigin</param-name>
			<param-value>http://XXX</param-value>
		</init-param>
		<init-param>
			<param-name>allowMethods</param-name>
			<param-value>GET,POST,PUT,DELETE,OPTIONS</param-value>
		</init-param>
		<init-param>
			<param-name>allowCredentials</param-name>
			<param-value>true</param-value>
		</init-param>
		<init-param>
			<param-name>allowHeaders</param-name>
			<param-value>Content-Type</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>corsFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

 

 

二、springMVC自带的配置

在SpringMVC 配置文件中 增加

<!--cors跨域支持-->
<mvc:cors>
   <mvc:mapping path="/**"
             allowed-origins="http://127.0.0.1:8020,http://127.0.0.1:8081"
             allowed-methods="GET,POST,PUT,DELETE,OPTIONS"
             allowed-headers="Content-Type,token"
             allow-credentials="true"
             max-age="123" />
</mvc:cors>

 

需要注意的有一点

 

1、通常我们在项目中都有增加拦截器、过滤器。

在跨域首次会发送OPTIONS申请。如果这时候被过滤器拦截下来。并且返回业务的错误信息。会提示跨域。

这里是因为在这个错误信息返回的时候没有走springMVC配置的CORS跨域配置。 所以需要手动在返回的响应中。增加这个

比如我这个权限校验的过滤器

 

@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {

		String method = request.getMethod();
		//options请求直接放行
		if(method.equals("OPTIONS")){
			return true;
		}

		//过滤不需要过滤接口
		boolean isOver = RenderUtil.inContainURL(request, jwtProperties.getJwt_noAuthPath());
		if (isOver) {
			return true;
		}

		String msg = "请登录后再操作";
		/*String content = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx582097e6b4749e25&redirect_uri=http%3A%2F%2Fapi.ruhexiu.com%2Frest-rp%2Fuser%2FwxLogin&response_type=code&scope=snsapi_userinfo&state=#wechat_redirect";*/
		Map<String, String> map = new HashMap<>();
		map.put("ret", "202");
		map.put("msg", msg);
		map.put("content",msg);

		final String requestHeader = request.getHeader(jwtProperties.getJwt_header());
		String authToken = null;
		if (requestHeader != null && requestHeader.startsWith("Bearer ")) {
			authToken = requestHeader.substring(7);

			//验证token是否过期,包含了验证jwt是否正确
			try {
				boolean flag = jwtTokenUtil.isTokenExpired(authToken);
				if (flag) {
					RenderUtil.renderJson(response, map,request);
					return false;
				}
			} catch (JwtException e) {
				//有异常就是token解析失败
				RenderUtil.renderJson(response, map,request);
				return false;
			}
		} else {
			//header没有带Bearer字段
			RenderUtil.renderJson(response, map,request);
			return false;
		}

		return true;
	}

 

比如上面在 

RenderUtil.renderJson(response, map,request);

这行代码的时候就会返回错误信息。所以在这个返回响应里面需要增加对CORS跨域的支持

  /**
     * 渲染json对象
     */
    public static void renderJson(HttpServletResponse response, Object jsonObject,HttpServletRequest request) {
        try {
            response.setContentType("application/json");
            response.setCharacterEncoding("UTF-8");
            //这里设置跨域
            response.setHeader("Access-Control-Allow-Origin",request.getHeader("Origin"));
            response.setHeader("Access-Control-Allow-Methods","GET,POST,PUT,DELETE,OPTIONS");
            response.setHeader("Access-Control-Allow-Headers","*");
            response.setHeader("Access-Control-Allow-Credentials","true");
            response.setHeader("Access-Control-Max-Age","123");

            PrintWriter writer = response.getWriter();
            writer.write(JSON.toJSONString(jsonObject));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

 

这样配置上springMVC提供的CORS配置。好使。

 

over~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值