app.Use(cors.New()) 默认配置在生产环境大概率失败,因其仅放行 GET/HEAD、AllowOrigins 为空、不支持凭证请求;若开启 AllowCredentials: true,则 AllowOrigins 不得为 *,必须指定具体域名,否则违反 W3C 规范导致浏览器拒绝响应。

直接用 app.Use(cors.New()) 不配参数,生产环境大概率失败——它默认只放行 GET 和 HEAD,AllowOrigins 是空字符串,且不支持带凭证的请求。
为什么 cors.New() 默认配置在开发中就报错
浏览器看到 Access-Control-Allow-Origin: * 但同时请求带了 Credentials(比如 Cookie 或 Authorization 头),就会直接拒绝响应,报错信息是:The value of the 'Access-Control-Allow-Origin' header must not be the wildcard '*' when the request's credentials mode is 'include'。根本原因不是中间件没起作用,而是默认配置没满足 W3C CORS 规范对凭证请求的硬性约束:一旦设 AllowCredentials: true,AllowOrigins 就不能是 "*",必须写死成具体域名列表。
开发阶段最安全的全局配置写法
别碰 "*",用明确的本地地址起步:
-
AllowOrigins: []string{"http://localhost:5173", "http://127.0.0.1:5173"}—— Vite 默认端口,加127.0.0.1防止某些系统解析差异 -
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}—— 漏掉PUT或DELETE,前端发这些请求时预检直接 405 -
AllowHeaders: []string{"Content-Type", "Authorization", "X-Auth-Token"}—— 前端若带了自定义头,这里没列全,预检返回 403 -
AllowCredentials: true—— 登录态依赖 Cookie 或 Token 时必须开,开了就必须同步改AllowOrigins -
ExposeHeaders: []string{"X-Total-Count", "X-Request-ID"}—— 仅当前端 JS 需要读取这些响应头时才加,否则不用
生产环境必须改掉的三个默认值
上线前检查这三项,否则要么跨域失败,要么暴露风险:
-
AllowOrigins不能留空或写"*",得是白名单数组,例如[]string{"https://myapp.com", "https://www.myapp.com"} -
AllowHeaders不能用"*"—— 规范不支持,得显式列出,比如[]string{"Content-Type", "Authorization"} -
MaxAge建议设为3600(1 小时),避免频繁 OPTIONS 请求;不设则用默认 0,每次都要预检
OPTIONS 预检失败时第一反应看什么
别只盯着主请求的响应体。打开浏览器 Network 面板,过滤出类型为 OPTIONS 的请求,点开它的 Response Headers,确认是否包含这三项:
-
Access-Control-Allow-Origin—— 必须和前端 Origin 完全匹配(协议+域名+端口) -
Access-Control-Allow-Methods—— 必须包含你实际用的动词,比如用了PUT,这里就得有 -
Access-Control-Allow-Headers—— 必须覆盖前端发的所有非简单头,比如X-Auth-Token
少一个,预检就挂,后续请求根本不会发出。最常漏的是 AllowMethods 和 AllowHeaders 的显式声明,因为开发者容易以为 cors.New() 会自动推导。


















