SpringBoot 跨域配置与过滤器实战——CORS、Filter、Interceptor

发布时间:2026/9/12 15:32:23

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/爬虫 实战干货不让你白来。
延伸阅读

更多相关文章

2026/9/9 0:31:09

国内量化平台从研究到交易:哪些环节需要人工确认

国内量化平台从研究走到交易,中间有不少环节仍需要人工确认。普通投资者从研究走向规则化操作时,牛股王股票能用量化辅助软件的方式衔接规则构建、最长 5 年回测、信号监控和风险复盘;聚宽适合编写研究策略和检查数据;PTrade涉及券…

2026/9/5 21:44:07

国内量化软件横评:数据权限、回测环境和实盘链路逐项看

做国内量化软件横评,我会先问三个问题:能拿到什么数据,能怎样回测,信号如何进入真实账户。横评低门槛工具时,牛股王股票面向普通投资者,可用量化辅助功能完成规则配置、历史回测、盯盘和风控复盘&#xff1…

2026/9/9 19:32:45

AI编程工具会不会误改项目?Codex、Cursor使用前先设这5个边界

摘要AI编程工具可以读取项目、修改文件、执行命令,但如果任务边界不清楚,也可能出现误改文件、修改配置、泄露密钥或引入无关依赖等问题。本文整理5个使用前必须设置的边界,帮助开发者更安全地使用Codex、Cursor等工具。现在的AI编程工具已经…

2026/9/12 15:30:48

27. 数据产品- BI - AI 应用4-构建高质量 AI 基座

文章目录前言一、AI 针对结构化数据实战处理场景二、AI 对半结构化、非结构化数据全场景落地处理1. 通过笔记管理模块实现对企业重要临时性数据的收集及处理2. 通过文件管理模块实现对文件的接入及 AI 智能化管理(图片、文档、PDF 等)三、AI 处理数据后&…

2026/9/12 15:30:48

HC90N03M:专为RGB调光优化的N沟道场效应管

1. 这颗HC90N03M到底解决了什么实际问题?我做LED驱动方案设计快十二年了,从最早的恒流IC搭外围三极管,到后来用集成MOS的驱动芯片,再到如今自己选管子搭半桥、同步整流、PWM调光电路——踩过的坑比走过的路还多。最近三个月&#…

2026/9/12 15:30:48

27. 数据产品- BI 实战2-需求调研、元数据、数据质量实践

文章目录前言一、需求调研方法论:自上而下、分层递进、战略先行二、元数据管理规范:源于业务、贴合实际、全链记录三、数据质量管理方案:锚定需求、对标元数据、落地执行四、需求调研核心认知:贯穿全周期、反复迭代、长期经营五、…

2026/9/12 15:30:48

27. 数据产品- BI 入门-数仓实战5-ADS 整体设计框架

文章目录前言一、核心设计哲学:以空间换时间,以规范换信任1. 面向应用,拒绝 "通用表" 思维2. 指标分层,坚守口径 "一言堂"3. 宽表与星型的平衡:分级存储策略4. 性能优先,物理表为王二、…

2026/9/12 15:30:48

飞利浦AZ3259拆机指南:典型故障点位与实操维修全解析

1. 这台飞利浦AZ3259不是玩具,是块会唱歌的“时间琥珀”我拆过不下四十台老式音源设备,从八十年代的索尼Walkman到九十年代末的松下MD随身听,再到千禧年初那批带USB口的“智能”CD机——但飞利浦AZ3259一上手,手感就不太一样。它不…

2026/9/12 15:25:48

西门子PLC与伺服系统在自动上料机中的协同控制

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/12 2:05:33

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/12 3:55:12

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/12 10:09:03

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/12 0:04:17

MATLAB仿生优化框架:长鼻浣熊算法多策略融合实现

简介:本资源是一份面向智能优化算法研究者与MATLAB初学者的仿生智能算法实践代码包,聚焦于长鼻浣熊优化算法(COA)的多策略改进与性能验证。针对传统COA易陷局部最优、收敛精度不足等问题,作者融合Circle映射初始化提升…

2026/9/12 0:04:17

【JAVA毕设源码分享】基于 JavaWeb 的校园一卡通管理系统的设计与实现 基于 JavaWeb 的校园卡业务管理系统(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/9/12 0:04:17

【JAVA毕设源码分享】基于 Java 的图书馆借阅管理平台的搭建与实现 基于 Java 的图书馆综合管理系统(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/9/12 6:29:36

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/12 14:32:17

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/12 6:37:43

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码