iris 框架需手动注册中间件处理 options 预检请求,因其路由层默认不拦截 options 方法,导致跨域预检失败且服务端无日志;必须用 app.useglobal 在所有路由前注册 cors 中间件,并正确设置响应头与状态码。

Iris 框架必须手动注册中间件处理 OPTIONS 预检请求,否则跨域请求直接失败且服务端无日志——这不是配置遗漏,而是框架设计使然。
为什么 Iris 不像 Gin 那样自动响应 OPTIONS
Iris 的路由层默认不拦截 OPTIONS 方法,浏览器发起带 Authorization 或自定义 header 的跨域请求时,预检阶段就已中断;服务端根本收不到该请求,自然也不会打日志。常见现象是控制台报 Response to preflight request doesn't pass access control check,但后端完全“静默”。
-
app.UseGlobal必须在所有路由注册前调用,否则中间件不生效 - 不能只在某个 handler 里写
ctx.Header("Access-Control-Allow-Origin", "..."),预检请求压根进不了那个 handler - 若前端发的是带凭证(
credentials: 'include')的请求,Access-Control-Allow-Origin就不能设为*,必须精确匹配Origin头
最简可用的 CORS 中间件写法
以下代码适配开发场景(如前端跑在 http://localhost:3000),可直接复制进 main.go:
app.UseGlobal(func(ctx iris.Context) {
origin := ctx.GetHeader("Origin")
if origin == "" {
ctx.Next()
return
}
if origin == "http://localhost:3000" || origin == "https://your-frontend.com" {
ctx.Header("Access-Control-Allow-Origin", origin)
ctx.Header("Access-Control-Allow-Credentials", "true")
ctx.Header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With, X-Api-Key")
ctx.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
ctx.Header("Access-Control-Expose-Headers", "Authorization")
ctx.Header("Access-Control-Max-Age", "3600")
}
if ctx.Method() == "OPTIONS" {
ctx.StatusCode(iris.StatusNoContent)
return
}
ctx.Next()
})
-
Access-Control-Allow-Headers要包含前端实际发送的自定义头,比如用了X-Api-Key,就必须加进去 -
Access-Control-Allow-Methods列出的动词必须覆盖你所有接口用到的 HTTP 方法,漏掉PUT就会导致 PUT 请求预检失败 - 生产环境务必把
origin == "http://localhost:3000"替换为白名单切片 + 循环比对,不能硬编码
容易被忽略的两个关键点
一是 Access-Control-Allow-Credentials: true 和 Access-Control-Allow-Origin: "*" 绝对不能共存,浏览器会直接拒绝;二是预检响应必须返回 204 No Content(或 200 OK),不能返回 200 加空 JSON——Iris 对 OPTIONS 的处理非常严格,状态码错一个字节都会让浏览器判定预检失败。











