直接用ctx.header()设置响应头需在statuscode或写响应体前调用,重复调用会覆盖;处理cors时须单独拦截options请求并返回204;追加同名头(如set-cookie)须用responsewriter().header().add()。

直接用 ctx.Header() 设置响应头
在 Iris 的请求处理函数或中间件中,调用 ctx.Header(key, value) 即可写入响应头。它底层调用的是标准 http.ResponseWriter.Header().Set(),所以行为和原生 Go 一致:重复调用会覆盖前值,不是追加。
常见用法:
ctx.Header("Content-Type", "application/json; charset=utf-8")-
ctx.Header("X-Request-ID", reqID)(配合日志追踪) ctx.Header("Cache-Control", "no-cache")
注意:ctx.Header() 必须在 ctx.StatusCode() 或任何写响应体(如 ctx.JSON()、ctx.WriteString())之前调用,否则可能被忽略——因为一旦响应开始写入,Header 就被锁定。
设置跨域响应头(CORS)要特别处理 OPTIONS 请求
浏览器预检(preflight)会发 OPTIONS 请求,如果没显式响应,前端就卡住。不能只靠 ctx.Header(),必须拦截并提前返回。
典型错误写法(不生效):
func Cors(ctx iris.Context) {
ctx.Header("Access-Control-Allow-Origin", "*")
ctx.Header("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,PATCH")
ctx.Next() // ❌ OPTIONS 请求仍会继续往下走,可能 404 或返回错误内容
}
正确做法:
- 检查
ctx.Method() == "OPTIONS" - 手动设置所有 CORS 头(包括
Access-Control-Allow-Headers) - 调用
ctx.StatusCode(204)并立即return,不执行后续 handler
示例:
func Cors(ctx iris.Context) {
ctx.Header("Access-Control-Allow-Origin", "*")
ctx.Header("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,PATCH,OPTIONS")
ctx.Header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With")
if ctx.Method() == "OPTIONS" {
ctx.StatusCode(204)
return
}
ctx.Next()
}
ctx.ResponseWriter().Header().Add() 和 Set() 的区别
ctx.Header(key, value) 是 Set() 的封装,等价于 ctx.ResponseWriter().Header().Set(key, value);若需追加多个同名 header(比如多个 Set-Cookie),必须用 Add()。
例如设置多个 Cookie:
rw := ctx.ResponseWriter()
rw.Header().Add("Set-Cookie", "session=abc; HttpOnly; Path=/")
rw.Header().Add("Set-Cookie", "theme=dark; Max-Age=3600; Path=/")
用 ctx.Header("Set-Cookie", ...) 只能设最后一个,前面的会被覆盖。
全局响应头建议统一在中间件里设置
像 X-Frame-Options、X-Content-Type-Options 这类安全头,适合在最外层中间件统一加,避免每个 handler 重复写。
但要注意顺序:中间件注册越早,执行越靠前。确保 app.Use(Cors) 在路由注册前,否则某些路由可能绕过。
容易被忽略的一点:ctx.Next() 后不能再调用 ctx.Header() —— 因为下游 handler 可能已经写了响应体,header 已冻结。如果需要动态改 header(比如根据业务逻辑加 X-RateLimit-Remaining),得在 ctx.Next() 前预留好变量,或用 ctx.OnResponse 钩子(Iris v12 支持)。











