SpringBoot 跨域配置与过滤器实战——CORS、Filter、Interceptor
前后端分离项目中跨域问题是最常见的拦路虎。这篇讲 SpringBoot 中三种解决跨域的方式以及 Filter 和 Interceptor 的区别与使用场景。一、什么是跨域1. 跨域的产生前端地址http://localhost:8080 后端地址http://localhost:9090 ↑ 端口不同产生了跨域 浏览器的同源策略 协议相同、域名相同、端口相同 → 同源 任何一个不同 → 跨域2. 跨域的表现浏览器控制台报错 Access to XMLHttpRequest at http://localhost:9090/api/users from origin http://localhost:8080 has been blocked by CORS policy二、三种跨域解决方案方案一CrossOrigin 注解最简单的方式在 Controller 或方法上加注解RestControllerRequestMapping(/api/users)CrossOrigin(originshttp://localhost:8080)publicclassUserController{// 整个类都允许跨域}// 或者只允许某个方法跨域GetMapping(/{id})CrossOrigin(origins*)// 允许所有来源publicResultVOUserget(PathVariableLongid){returnResultVO.success(userService.getById(id));}缺点每个 Controller 都要加维护麻烦。方案二全局配置推荐ConfigurationpublicclassCorsConfigimplementsWebMvcConfigurer{OverridepublicvoidaddCorsMappings(CorsRegistryregistry){registry.addMapping(/api/**)// 允许跨域的路径.allowedOriginPatterns(*)// 允许的域名.allowedMethods(GET,POST,PUT,DELETE,OPTIONS).allowedHeaders(*).allowCredentials(true)// 允许携带 Cookie.maxAge(3600);// 预检请求缓存时间}}注意allowCredentials(true)和allowedOriginPatterns(*)必须同时使用不能单独用allowedOrigins(*)否则会报错。方案三Filter 手动处理ComponentOrder(1)publicclassCorsFilterimplementsFilter{OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{HttpServletResponseresp(HttpServletResponse)response;resp.setHeader(Access-Control-Allow-Origin,*);resp.setHeader(Access-Control-Allow-Methods,GET,POST,PUT,DELETE,OPTIONS);resp.setHeader(Access-Control-Allow-Headers,*);resp.setHeader(Access-Control-Max-Age,3600);// 预检请求直接返回if(OPTIONS.equalsIgnoreCase(((HttpServletRequest)request).getMethod())){resp.setStatus(HttpServletResponse.SC_OK);return;}chain.doFilter(request,response);}}三、Filter vs Interceptor对比Filter过滤器Interceptor拦截器层级Servlet 层面Spring 层面范围所有请求只有进入 Controller 的请求操作HttpServletRequest/Response方法调用前后处理使用场景CORS、编码、鉴权 Token 校验登录校验、日志记录、权限验证Filter 典型场景请求日志ComponentOrder(2)publicclassRequestLogFilterimplementsFilter{privatestaticfinalLoggerlogLoggerFactory.getLogger(RequestLogFilter.class);OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{HttpServletRequestreq(HttpServletRequest)request;longstartSystem.currentTimeMillis();chain.doFilter(request,response);longdurationSystem.currentTimeMillis()-start;log.info({} {} {} - {}ms,req.getMethod(),req.getRequestURI(),response.getContentType(),duration);}}Interceptor 典型场景登录校验ComponentpublicclassLoginInterceptorimplementsHandlerInterceptor{OverridepublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{// 从请求头获取 TokenStringtokenrequest.getHeader(Authorization);if(tokennull||token.isEmpty()){response.setStatus(401);response.setContentType(application/json);response.getWriter().write({\code\:401,\message\:\未登录\});returnfalse;}// 校验 Token省略具体逻辑// if (!TokenUtil.validate(token)) { return false; }returntrue;}}ConfigurationpublicclassInterceptorConfigimplementsWebMvcConfigurer{AutowiredprivateLoginInterceptorloginInterceptor;OverridepublicvoidaddInterceptors(InterceptorRegistryregistry){registry.addInterceptor(loginInterceptor).addPathPatterns(/api/**).excludePathPatterns(/api/login,/api/register,/doc.html);}}四、XSS 过滤器ComponentOrder(3)publicclassXssFilterimplementsFilter{OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{chain.doFilter(newXssHttpServletRequestWrapper((HttpServletRequest)request),response);}/** * 包装请求过滤 XSS 脚本 */staticclassXssHttpServletRequestWrapperextendsHttpServletRequestWrapper{publicXssHttpServletRequestWrapper(HttpServletRequestrequest){super(request);}OverridepublicStringgetParameter(Stringname){Stringvaluesuper.getParameter(name);returncleanXss(value);}OverridepublicString[]getParameterValues(Stringname){String[]valuessuper.getParameterValues(name);if(valuesnull)returnnull;String[]cleanednewString[values.length];for(inti0;ivalues.length;i){cleaned[i]cleanXss(values[i]);}returncleaned;}privateStringcleanXss(Stringvalue){if(valuenull)returnnull;// 过滤常见 XSS 关键字valuevalue.replaceAll(script,).replaceAll(/script,).replaceAll(onerror,).replaceAll(onclick,);returnvalue;}}}五、Filter 的执行顺序/** * 多个 Filter 的执行顺序 * * CorsFilterOrder(1)→ RequestLogFilterOrder(2)→ XssFilterOrder(3) * ↓ * DispatcherServlet → InterceptorpreHandle * ↓ * Controller * ↓ * InterceptorpostHandle * ↓ * InterceptorafterCompletion * ↓ * Filter反向执行 */执行顺序请求进来 → CorsFilter.doFilter() → RequestLogFilter.doFilter() → XssFilter.doFilter() → LoginInterceptor.preHandle() → Controller 方法 → LoginInterceptor.afterCompletion() → XssFilter.doFilter() 结束 → RequestLogFilter.doFilter() 结束 → CorsFilter.doFilter() 结束 → 响应返回六、常见问题1. OPTIONS 预检请求浏览器在发送真正的跨域请求之前会先发一个 OPTIONS 请求 检查服务器是否允许跨域 如果 OPTIONS 请求没有正常返回真正的请求也不会发出2. 携带 Cookie 的跨域// 前端需要设置axios.defaults.withCredentialstrue;// 后端不能使用 allowedOrigins(*)// 必须指定具体的域名allowedOriginPatterns(http://localhost:8080)allowCredentials(true)3. Nginx 解决跨域server { listen 80; location /api/ { proxy_pass http://localhost:9090/; # 跨域配置 add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods GET, POST, OPTIONS; if ($request_method OPTIONS) { return 204; } } }七、秒杀系统的跨域配置ConfigurationpublicclassSeckillWebConfigimplementsWebMvcConfigurer{OverridepublicvoidaddCorsMappings(CorsRegistryregistry){registry.addMapping(/api/**).allowedOriginPatterns(*).allowedMethods(GET,POST,PUT,DELETE).allowCredentials(true).maxAge(3600);}OverridepublicvoidaddInterceptors(InterceptorRegistryregistry){registry.addInterceptor(newSeckillInterceptor()).addPathPatterns(/api/seckill/**).excludePathPatterns(/api/seckill/init/**);}}总结简单跨域 → CrossOrigin临时调试用 生产环境 → 全局 CORS 配置WebMvcConfigurer 特殊需求 → Filter 手动处理 权限校验 → InterceptorSpring 层面更灵活 觉得有用的话点赞 关注【张老师技术栈】吧每周更新 Java/Python/爬虫 实战干货不让你白来。

相关新闻

Codex多任务并行怎么用?GPT-5.6下的代码任务拆分思路

Codex多任务并行怎么用?GPT-5.6下的代码任务拆分思路

摘要Codex支持多任务并行,适合把大型开发需求拆成多个小任务处理。本文结合GPT-5.6下的模型选择,介绍前端、后端、测试和文档任务如何拆分,以及并行执行时如何减少文件冲突和返工。使用Codex做项目开发时,很多人习惯直接输入一句&…

2026/7/14 1:03:36 阅读更多 →
2026年多商户商城系统哪个好?商家入驻、分账和权限对比

2026年多商户商城系统哪个好?商家入驻、分账和权限对比

2026年多商户商城系统哪个好?商家入驻、分账和权限对比多商户商城系统哪个好,不能只看能不能上架商品。平台型业务和单店商城不一样,核心在商家能不能入驻,平台能不能审核商品,订单和售后责任怎么划分,平台…

2026/7/14 0:59:35 阅读更多 →
HarmonyOS APP实战-画图APP - 第14篇:可变帧率与性能优化

HarmonyOS APP实战-画图APP - 第14篇:可变帧率与性能优化

HarmonyOS APP实战-画图APP - 第14篇:使用displaySync定制绘制帧率 开篇 上一篇我们完成了本地数据库存储与读取功能:通过关系型数据库(RdbStore)保存了画作元数据(名称、创建时间、缩略图路径)&#xff0c…

2026/7/14 0:57:34 阅读更多 →

最新新闻

从PyTorch到TensorRT:ESRGAN超分辨率模型5倍推理加速实战

从PyTorch到TensorRT:ESRGAN超分辨率模型5倍推理加速实战

从PyTorch到TensorRT:ESRGAN超分辨率模型5倍推理加速实战 【免费下载链接】PyTorch-GAN PyTorch implementations of Generative Adversarial Networks. 项目地址: https://gitcode.com/gh_mirrors/py/PyTorch-GAN 在生成对抗网络的实际部署中,我…

2026/7/14 11:56:29 阅读更多 →
三十.全连接神经网络:从结构到训练的全链路解析

三十.全连接神经网络:从结构到训练的全链路解析

1. 全连接神经网络的结构解析全连接神经网络(Fully Connected Neural Network)是深度学习中最基础的架构之一,它的核心特点是相邻层之间的神经元全部相互连接。想象一下城市之间的交通网:输入层像是出发站,隐藏层是中转…

2026/7/14 11:54:28 阅读更多 →
MIPI CSI-2固定色彩模式测试:数据块大小配置与DS90UB635-Q1实战

MIPI CSI-2固定色彩模式测试:数据块大小配置与DS90UB635-Q1实战

1. 项目概述:为什么我们需要固定色彩模式测试?在嵌入式视觉系统,尤其是汽车摄像头、工业相机或者手机摄像模组的开发过程中,图像传感器接口的调试与验证是一个既基础又关键的环节。想象一下,你设计了一个复杂的图像处理…

2026/7/14 11:54:28 阅读更多 →
大模型微调中Loss与准确率的关系及优化策略

大模型微调中Loss与准确率的关系及优化策略

1. 大模型微调训练中的Loss与准确率关系解析在大模型微调训练过程中,Loss值和准确率是两个最直观的指标,但很多开发者对它们之间的关系存在误解。最近在微调Qwen2-7B模型时,我发现一个有趣现象:验证集Loss持续下降,但准…

2026/7/14 11:52:28 阅读更多 →
SAP MM实战解析:从101到124,解锁移动类型在收货与退货中的核心逻辑与场景应用

SAP MM实战解析:从101到124,解锁移动类型在收货与退货中的核心逻辑与场景应用

1. SAP MM移动类型基础概念解析 第一次接触SAP MM模块的移动类型时,我完全被那一串三位数代码搞懵了。101、103、122...这些数字背后到底藏着什么秘密?经过多年实战才明白,移动类型其实就是SAP用来区分不同物料移动场景的"身份证号"…

2026/7/14 11:52:28 阅读更多 →
【技术解析】CORAL:为神经网络序数回归注入一致性保证

【技术解析】CORAL:为神经网络序数回归注入一致性保证

1. 序数回归的痛点与CORAL的诞生在深度学习领域,我们常常遇到需要预测有序标签的任务,比如年龄估计、疾病严重程度分级等。这类问题被称为序数回归(Ordinal Regression),它介于分类和回归之间——标签有明确的顺序关系…

2026/7/14 11:50:27 阅读更多 →

日新闻

AI Agent数据越界行为如何被精准溯源?——基于GDPR/CCPA双合规的5层审计框架实战指南

AI Agent数据越界行为如何被精准溯源?——基于GDPR/CCPA双合规的5层审计框架实战指南

更多请点击: https://kaifayun.com 第一章:AI Agent数据越界行为的合规性挑战与溯源必要性 AI Agent在自主执行任务过程中,可能因提示注入、上下文污染或权限配置缺陷,无意或有意访问、缓存、传输受保护数据(如PII、G…

2026/7/14 0:01:13 阅读更多 →
Perplexity vs ChatGPT vs Claude:实测127组复杂查询任务,谁才是真正可靠的“事实型AI助手”?

Perplexity vs ChatGPT vs Claude:实测127组复杂查询任务,谁才是真正可靠的“事实型AI助手”?

更多请点击: https://codechina.net 第一章:Perplexity 怎么用 Perplexity 是衡量语言模型预测能力的核心指标,数值越低表示模型对文本序列的不确定性越小、预测越精准。它本质上是交叉熵损失的指数形式,计算公式为:…

2026/7/14 0:01:13 阅读更多 →
全球首发!五一视界定制物理AI卫星ECS-1剑指万亿赛道

全球首发!五一视界定制物理AI卫星ECS-1剑指万亿赛道

五一视界发布公告,近日,公司与环天智慧科技股份有限公司(“环天智慧”)正式达成空天领域战略合作。环天智慧是国内领先、聚焦天基对地观测遥感卫星总体研制与在轨运营的商业航天企业,同时也是西南地区规模最大、具备全自主可控遥感卫星星座建…

2026/7/14 0:03:13 阅读更多 →

周新闻

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨 在一个阳光明媚的上午,互联网大厂的面试官坐在桌前,准备迎接他的面试候选人——燕双非,一个以搞笑和幽默著称的程序员。第一轮提问 面试官:燕双非,作…

2026/7/13 4:38:36 阅读更多 →
车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估

车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估

车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估在智能驾驶和车联网技术快速发展的今天,车载以太网作为新一代车载网络的核心传输技术,其物理层性能直接决定了数据传输的可靠性和稳定性。1000BASE-T1作为当前主流的…

2026/7/13 4:38:38 阅读更多 →
VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战,5步完成Keil工程转换

VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战,5步完成Keil工程转换

VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战指南嵌入式开发领域正经历一场工具链的静默革命。当传统Keil用户首次打开VSCode的扩展市场搜索EIDE时,往往会惊讶于这个看似简单的插件竟能重构十余年的开发习惯。本文将揭示如何用五个精准步骤&#xff0…

2026/7/14 7:15:24 阅读更多 →

月新闻