更换Supabase数据库后无代码改动却遇CORS请求错误,如何解决?
问题分析与解决方案
核心矛盾点拆解
你遇到的问题本质是浏览器预检请求(OPTIONS)未被正确响应:POST/DELETE属于非简单请求,浏览器会先发送OPTIONS请求确认服务器允许跨域操作,而curl直接发送请求不会触发预检,这就是curl正常但前端报错的原因。虽然你只修改了数据库URL,但部署过程中的隐性变化(比如Go版本升级)可能间接影响了HTTP头的处理逻辑。
现有代码的关键缺陷
你的enableCors函数仅在DELETE/POST分支中调用,但OPTIONS请求根本不会进入这些分支,导致浏览器的预检请求得不到合法的CORS响应头,直接触发跨域拦截。此外,当前CORS配置缺少对允许方法的声明,浏览器无法确认服务器支持DELETE/POST这类操作。
分步修复方案
1. 全局拦截并处理OPTIONS预检请求
在API路由的最前端添加全局OPTIONS处理逻辑,确保所有预检请求都能得到正确响应:
func main() { http.HandleFunc("/api/v1/friends/friend/", func(w http.ResponseWriter, r *http.Request) { // 优先处理OPTIONS预检请求 if r.Method == http.MethodOptions { enableCors(&w) w.Header().Set("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS") w.WriteHeader(http.StatusOK) return } // 原有请求逻辑放在这里 if r.Method == http.MethodDelete { enableCors(&w) // 你的DELETE业务代码... } else if r.Method == http.MethodPost { enableCors(&w) // 你的POST业务代码... } else if r.Method == http.MethodGet { enableCors(&w) // 你的GET业务代码... } }) }
2. 完善CORS头配置
更新enableCors函数,补充必要的跨域字段:
func enableCors(w *http.ResponseWriter) { (*w).Header().Set("Access-Control-Allow-Origin", "*") (*w).Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") (*w).Header().Set("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS") (*w).Header().Set("Access-Control-Max-Age", "3600") // 缓存预检结果1小时,减少重复请求 }
3. 锁定Go版本排除部署环境影响
你怀疑Go版本从1.16升级到1.23,可在fly.toml中添加构建配置强制指定版本:
[build] go_version = "1.16"
避免部署环境自动使用新版本导致的隐性兼容问题。
4. 前端代码优化(非核心但更健壮)
用模板字符串拼接URL并编码参数,避免特殊字符引发的URL解析问题:
const onDelete = () => { axios({ method: "delete", url: `https://blah.com/api/v1/friends/friend/?friend=${encodeURIComponent(friend.FriendName)}`, headers: { "Content-Type": "application/json" }, }) .then(response => { console.log(response); navigate("/"); }) .catch(error => { console.log(error); }); };
验证流程
- 部署修改后的API到fly.io
- 打开浏览器开发者工具的Network面板,触发DELETE请求
- 检查OPTIONS请求的响应头,确认包含
Access-Control-Allow-Origin、Access-Control-Allow-Methods等字段 - 确认实际DELETE请求能正常发送并返回预期响应
内容的提问来源于stack exchange,提问作者Victor
相关产品推荐
相关产品推荐

