发布时间:2026/8/7 11:22:35
第28篇-CORS与文件上传 【Kotlin Spring Boot 4 从零到架构师】第 28 篇CORS 与文件上传本系列定位零基础入门从 Kotlin 语法一路到 Spring Boot 4 高级架构DDD Modulith适合 Java 开发者转型也适合纯新手系统学习。本篇你将学到CORS 跨域问题的原因与解决方案Spring Boot 全局 CORS 配置文件上传MultipartFile文件下载ResponseEntity 流学完本篇你将能为 mini-shop 添加跨域支持和商品图片上传功能。一、CORS 跨域下面是 CORS 跨域请求的完整流程示意图后端 API(localhost:8080)前端页面(localhost:3000)浏览器后端 API(localhost:8080)前端页面(localhost:3000)浏览器浏览器检测到端口不同 → 跨域检查响应头是否允许当前源alt[允许跨域][不允许跨域]用户访问页面发送跨域请求 (GET /api/products)响应 Access-Control-Allow-Origin 头正常处理响应数据抛出 CORS 错误阻止 JS 读取1.1 什么是跨域当浏览器的前端页面和后端 API 不在同一个「源」协议域名端口时浏览器会阻止请求前端http://localhost:3000 Vite/Vue 开发服务器 后端http://localhost:8080 Spring Boot 协议相同http、域名相同localhost、端口不同3000 vs 8080 → 浏览器判定为跨域 → 默认阻止请求1.2 错误现象浏览器控制台报错Access to XMLHttpRequest at http://localhost:8080/api/products from origin http://localhost:3000 has been blocked by CORS policy: No Access-Control-Allow-Origin header is present on the requested resource.1.3 解决方案全局 CORS 配置packagecom.example.minishop.configimportorg.springframework.context.annotation.Configurationimportorg.springframework.web.servlet.config.annotation.CorsRegistryimportorg.springframework.web.servlet.config.annotation.WebMvcConfigurerConfigurationclassCorsConfig:WebMvcConfigurer{overridefunaddCorsMappings(registry:CorsRegistry){registry.addMapping(/api/**) // 对 /api/ 下所有接口生效 .allowedOrigins( // 允许的前端源 http://localhost:3000, // Vue/Vite 开发服务器 http://localhost:5173, // Vue 默认端口 http://localhost:4200 // Angular 默认端口 ) .allowedMethods(GET, POST, PUT, DELETE, OPTIONS) .allowedHeaders(*) // 允许所有请求头 .allowCredentials(true) // 允许携带 Cookie .maxAge(3600) // 预检请求缓存 1 小时 } }1.4 生产环境 CORSConfigurationclassCorsConfig:WebMvcConfigurer{overridefunaddCorsMappings(registry:CorsRegistry){registry.addMapping(/api/**) // 生产环境只允许前端域名 .allowedOrigins( https://www.mini-shop.com, https://mini-shop.com ) .allowedMethods(GET, POST, PUT, DELETE) .allowedHeaders(*) .allowCredentials(true) .maxAge(3600) } }安全提示不要在生产环境用allowedOrigins(*)allowCredentials(true)这会被浏览器拒绝。如果允许任意域名用allowedOriginPatterns(*)。1.5 单个接口的 CORS如果只有个别接口需要跨域RestControllerRequestMapping(/api/products)CrossOrigin(origins[http://localhost:3000])// 类级别classProductController{GetMapping(/{id})CrossOrigin(origins[http://localhost:5173])// 方法级别fungetById(PathVariableid:Long):Product{...}}二、文件上传下面是文件上传的完整处理流程图是否否是客户端发起上传请求文件是否为空抛出 BusinessRuleException文件不能为空文件类型是否允许抛出 BusinessRuleException不支持的文件类型生成唯一文件名UUID 原始扩展名创建目标目录Files.createDirectories()写入文件到磁盘Files.copy()返回文件信息文件名/大小/URL前端获取 URL展示上传结果2.1 配置上传限制spring:servlet:multipart:enabled:truemax-file-size:10MB# 单个文件最大 10MBmax-request-size:50MB# 单次请求最大 50MB2.2 文件上传接口packagecom.example.minishop.controllerimportcom.example.minishop.exception.BusinessRuleExceptionimportcom.example.minishop.dto.ApiResponseimportorg.springframework.beans.factory.annotation.Valueimportorg.springframework.web.bind.annotation.*importorg.springframework.web.multipart.MultipartFileimportjava.nio.file.Filesimportjava.nio.file.Pathimportjava.nio.file.Pathsimportjava.nio.file.StandardCopyOptionimportjava.util.UUIDRestControllerRequestMapping(/api/files)classFileController(// 从配置文件读取上传目录Value(\${mini-shop.upload-dir:uploads})privatevaluploadDir:String){PostMapping(/upload)funupload(RequestParam(file)file:MultipartFile,RequestParam(defaultValueproduct)type:String):ApiResponseMapString,String{// 1. 校验文件if(file.isEmpty){throwBusinessRuleException(文件不能为空)}valoriginalFilenamefile.originalFilename?:throwBusinessRuleException(文件名不能为空)// 2. 校验文件类型valallowedExtensionssetOf(jpg,jpeg,png,gif,webp)valextensionoriginalFilename.substringAfterLast(.,).lowercase()if(extension!inallowedExtensions){throwBusinessRuleException(不支持的文件类型.$extension)}// 3. 生成唯一文件名防止覆盖valnewFilename${type}/${UUID.randomUUID()}.$extension// 4. 创建目录并保存valtargetPath:PathPaths.get(uploadDir,newFilename)Files.createDirectories(targetPath.parent)// 5. 写入文件file.inputStream.use{input-Files.copy(input,targetPath,StandardCopyOption.REPLACE_EXISTING)}// 6. 返回文件信息returnApiResponse.success(mapOf(filenametonewFilename,originalNametooriginalFilename,sizetofile.size.toString(),urlto/uploads/$newFilename))}}2.3 上传测试curl-XPOST http://localhost:8080/api/files/upload\-Ffilekeyboard.jpg\-Ftypeproduct响应{code:200,message:success,data:{filename:product/550e8400-e29b-41d4-a716-446655440000.jpg,originalName:keyboard.jpg,size:245678,url:/uploads/product/550e8400-e29b-41d4-a716-446655440000.jpg}}2.4 静态资源映射上传的文件需要能被访问到配置静态资源映射ConfigurationclassWebConfig:WebMvcConfigurer{overridefunaddResourceHandlers(registry:ResourceHandlerRegistry){// 把 /uploads/** URL 映射到本地文件目录registry.addResourceHandler(/uploads/**) .addResourceLocations(file:uploads/) } }三、文件下载下面是文件下载的流程示意图否是客户端请求下载/download/{filename}文件是否存在抛出 ResourceNotFoundException探测文件 ContentType设置响应头Content-Disposition: attachmentFiles.copy()写入响应输出流浏览器触发下载GetMapping(/download/{filename})fundownload(PathVariablefilename:String,response:HttpServletResponse){valfilePath:PathPaths.get(uploadDir,filename)if(!Files.exists(filePath)){throwResourceNotFoundException(文件,filename)}valcontentTypeFiles.probeContentType(filePath)?:application/octet-streamresponse.contentTypecontentType response.setHeader(Content-Disposition,attachment; filename\$filename\)Files.copy(filePath,response.outputStream)}本篇小结知识点核心内容CORS浏览器安全策略阻止跨源请求全局 CORS 配置WebMvcConfigurer.addCorsMappings()CrossOrigin单个接口的跨域配置allowedOrigins允许的前端域名allowCredentials允许携带 Cookie文件上传RequestParam(file) MultipartFile上传限制spring.servlet.multipart.max-file-size文件名防覆盖UUID 生成唯一文件名文件下载Files.copy(path, response.outputStream)静态资源映射addResourceHandler(/uploads/**)下篇预告第 29 篇SpringDoc OpenAPI 3 — API 文档一行代码不写就能生成漂亮的 API 文档下一篇集成 SpringDoc为 mini-shop 生成交互式 API 文档。如果本篇内容对你有帮助欢迎点赞收藏有任何疑问欢迎在评论区交流。

相关新闻

2026/8/7 11:22:35

做小程序商城多少钱?年费、页面设计、交易功能和长期维护拆解

做小程序商城多少钱?年费、页面设计、交易功能和长期维护拆解企业问做小程序商城多少钱,已经不能只看一个首年报价。商城费用要拆成年费版本、页面定制设计、交易功能、支付配置、会员营销、配送/自提/核销、售后培训、续费维护和可能的定制开发成本。很…

2026/8/7 11:22:35

第27篇-拦截器与过滤器

【Kotlin Spring Boot 4 从零到架构师】第 27 篇:拦截器与过滤器 本系列定位:零基础入门,从 Kotlin 语法一路到 Spring Boot 4 高级架构(DDD Modulith),适合 Java 开发者转型,也适合纯新手系统…

2026/8/7 13:17:44

3分钟掌握Windows虚拟光驱:WinCDEmu开源免费完整指南

3分钟掌握Windows虚拟光驱:WinCDEmu开源免费完整指南 【免费下载链接】WinCDEmu 项目地址: https://gitcode.com/gh_mirrors/wi/WinCDEmu 还在为ISO、IMG等光盘镜像文件无法直接访问而烦恼吗?今天我要向你介绍一款功能强大且完全免费的开源虚拟光…

2026/8/7 13:17:44

KKS-HF_Patch终极指南:为Koikatsu Sunshine带来完整增强体验

KKS-HF_Patch终极指南:为Koikatsu Sunshine带来完整增强体验 【免费下载链接】KKS-HF_Patch Automatically translate, uncensor and update Koikatsu Sunshine! 项目地址: https://gitcode.com/gh_mirrors/kk/KKS-HF_Patch KKS-HF_Patch是一款专为《Koikats…

2026/8/7 13:17:44

PL2303驱动终极修复指南:Windows 10/11下让旧款芯片重获新生

PL2303驱动终极修复指南:Windows 10/11下让旧款芯片重获新生 【免费下载链接】pl2303-win10 Windows 10 driver for end-of-life PL-2303 chipsets. 项目地址: https://gitcode.com/gh_mirrors/pl/pl2303-win10 还在为Windows 10/11系统中PL2303串口设备无法…

2026/8/7 13:17:44

Android性能优化实战:Perfetto抓取与深度分析全流程指南

1. 项目概述:为什么我们需要Perfetto来抓取Trace? 在移动应用开发,尤其是Android生态里,性能问题就像房间里的大象,人人都知道它存在,但真要把它揪出来、看清楚,却没那么容易。卡顿、掉帧、耗电…

2026/8/5 3:13:11

如何用免费工具突破游戏窗口限制:SRWE完整使用指南

如何用免费工具突破游戏窗口限制:SRWE完整使用指南 【免费下载链接】SRWE Simple Runtime Window Editor 项目地址: https://gitcode.com/gh_mirrors/sr/SRWE 你是否遇到过这样的困扰?想为心爱的游戏截图,却发现游戏不支持自定义分辨率…

2026/8/7 0:01:55

CAD图库管理:从文件归档到设计资产管理的效率革命

你肯定遇到过这种情况:打开一个老项目,想找某个特定的图块——比如一个标准的门、一个特定的设备符号,或者一个公司logo。你记得它就在某个DWG文件里,或者曾经从某个同事那里拷来过。于是,你开始在一堆命名混乱的文件夹…

2026/8/7 0:01:55

5分钟掌握Wand-Enhancer:2026年终极WeMod专业版免费解锁指南

5分钟掌握Wand-Enhancer:2026年终极WeMod专业版免费解锁指南 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/GitHub_Trending/we/Wand-Enhancer Wand-Enhancer是一款功能强…

2026/8/7 0:01:55

“Quality Control(质量控制)”在软件工程中通常指通过一系列活动确保软件产品符合预定的质量标准和用户需求

“Quality Control(质量控制)”在软件工程中通常指通过一系列活动确保软件产品符合预定的质量标准和用户需求。而“软件测试”是质量控制的关键手段之一,属于QC范畴下的具体实践,其目标是发现缺陷、验证功能正确性、评估软件质量属…

2026/8/7 9:44:18

实测才敢推 AI论文网站 2026最新测评与推荐

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。一、综…

2026/8/5 19:21:13

2026必备!AI论文网站测评:最新推荐与深度对比

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

2026/8/6 20:45:01

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…