拦截器和跨域问题(转载)
拦截器解决跨域问题
梦梁鹿 于 2022-03-03 16:58:06 发布 6161 收藏 7
文章标签: java web安全
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_45155235/article/details/123257256
版权
拦截器解决跨域问题
注:本文是用SpringBoot + Dubbo搭建的分布式工程,前后端分离,前端工程和后端工程的端口号不同,所以产生了前端请求跨域问题。
拦截器定义
注意,前端的请求域名如果是80端口,直接指定为"http://localhost",其他端口才具体指定。
如果你的项目有多个客户端域名,那么可以指定一个数组,如下:
// 设置允许多个域名请求
String[] allowDomains = {"http://localhost:8081","http://localhost:8082"};
Set<String> allowOrigins = new HashSet<String>(Arrays.asList(allowDomains));
String originHeads = httpServletRequest.getHeader("Origin");
if(allowOrigins.contains(originHeads)){
}
// 跨域请求处理拦截器
@Component
public class CorsInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 指定前端的请求域名
String allowDomain = "http://localhost";
String originHeads = request.getHeader("Origin");
if(allowDomain.equals(originHeads)){
//设置允许跨域的配置
// 这里填写你允许进行跨域的主机ip(正式上线时可以动态配置具体允许的域名和IP)
response.setHeader("Access-Control-Allow-Origin", originHeads);
}
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Headers",
"Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
response.setHeader("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
response.setHeader("X-Powered-By", "Jetty");
String method = request.getMethod();
if (method.equals("OPTIONS")) {
response.setStatus(200);
return false;
}
return true;
}
}
注意:拦截器与过滤器功能相似,使用相同逻辑的过滤器也能解决跨域问题,如下:
@Component
public class CorsFilterConfig implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("x-frame-options", "SAMEORIGIN");
// 不使用*,自动适配跨域域名,避免携带Cookie时失效
String origin = request.getHeader("Origin");
if (StringUtils.isNotBlank(origin)) {
response.setHeader("Access-Control-Allow-Origin", origin); }
// 自适应所有自定义头
String headers = request.getHeader("Access-Control-Request-Headers");
if(StringUtils.isNotBlank(headers)) {
response.setHeader("Access-Control-Allow-Headers", headers);
response.setHeader("Access-Control-Expose-Headers", headers);
}
// 允许跨域的请求方法类型
response.setHeader("Access-Control-Allow-Methods", "*");
// 预检命令(OPTIONS)缓存时间,单位:秒
response.setHeader("Access-Control-Max-Age", "3600");
// 明确许可客户端发送Cookie,不允许删除字段即可
response.setHeader("Access-Control-Allow-Credentials", "true");
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
拦截器配置
注意:如果项目中还有其他拦截器,应该配置在CorsInterceptor 之后,保证CorsInterceptor 解决跨域请求问题后,才放行到其他拦截器。
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Autowired
private CorsInterceptor corsInterceptor;
/*
* 在配置类中指定拦截器的相关配置*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 拦截所有请求
String[] addPaths = {
"/**"
};
String[] excludePaths = {
"/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg", "/**/*.jpeg"
};
registry.addInterceptor(corsInterceptor).addPathPatterns(addPaths).excludePathPatterns(excludePaths);
}
}
前端请求配置
跨域问题是前后端一起解决的,如果项目使用到Cookie,前端请求函数也要做相应的配置。
如果使用Vue axios,配置如下:
// 允许携带cookie
axio.withCredentials = true;
axio.defaults.withCredentials = true;
如果使用AJAV,配置如下:
$.ajax({
url: SERVER_URL + "/ticket/check",
type: "post",
xhrFields: {
withCredentials: true //解决跨服务传递时不传递cookie的问题,允许携带证书
},
crossDomain: true, //允许跨域
contentType:'application/json',
data:JSON.stringify({}),
dataType: "json",
success:function (resp) {
},
});
梦梁鹿
关注
1
点赞
踩
7
收藏
打赏
打赏
0
评论
拦截器解决跨域问题
拦截器解决跨域问题注:本文是用SpringBoot + Dubbo搭建的分布式工程,前后端分离,前端工程和后端工程的端口号不同,所以产生了前端请求跨域问题。拦截器定义注意,前端的请求域名如果是80端口,直接指定为"http://localhost",其他端口才具体指定。如果你的项目有多个客户端域名,那么可以指定一个数组,如下: // 设置允许多个域名请求 String[] allowDomains = {"http://localhost:8081","http://localhost:80