在项目开发中,时常会遇到跨域问题,常用的方法有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;
}
}
网友评论