Iris.Router 默认不拦截非法HTTP动词是因为其“动词优先”设计:未注册路径+非法动词返回404,已注册路径+非法动词才返回405;需用app.UseRouter结合Lookup精确拦截,并注意OPTIONS预检与白名单顺序。

为什么 iris.Router 默认不拦截非法 HTTP 动词?
因为 Iris 的路由匹配是“动词优先”设计:它先查是否有注册了对应 GET、POST 等方法的 handler,没匹配到就直接返回 405(Method Not Allowed)——但前提是该路径存在其他合法动词。如果某路径压根没注册任何动词(比如 /api/v1/users 完全没调用过 Get/Post 等),Iris 默认会继续往下走中间件,最终可能落到 404,而不是 405。
也就是说:**未注册路径 + 非法动词 → 404;已注册路径 + 非法动词 → 405**。这容易让人误以为“非法动词被放行了”,其实只是路径本身不存在。
用 app.UseRouter 拦截所有未注册动词请求
最稳妥的方式是在全局中间件里检查 ctx.Method() 和当前路由是否匹配。Iris 提供了 ctx.GetCurrentRoute(),但它在未命中路由时返回 nil,所以不能只靠它判断。
推荐做法是:在 app.UseRouter(注意不是 Use)中提前拦截,利用 Iris 内部的路由查找逻辑:
app.UseRouter(func(ctx iris.Context) {
method := ctx.Method()
path := ctx.Path()
// 尝试手动查找该 path 下是否有 method 对应的路由
route := app.GetRouter().Lookup(method, path)
if route == nil {
// 注意:这里要排除常见健康检查路径,如 /health、/ping,避免误杀
if path != "/health" && path != "/ping" && !strings.HasPrefix(path, "/static/") {
ctx.StatusCode(405)
ctx.WriteString("Method Not Allowed")
return
}
}
ctx.Next()
})
-
app.UseRouter在路由匹配前执行,比Use更早,能真正“拦截未注册动词” -
app.GetRouter().Lookup(method, path)是 Iris 底层暴露的精确匹配方法,返回*iris.Route或nil - 别漏掉对静态资源路径(如
/static/)、健康检查路径的白名单,否则 CSS/JS 可能 405
为什么不用 app.Any 或 app.OnErrorCode(404)?
这两个方案看似简单,但实际有明显缺陷:
当代理已经知道网站路由或内容URL,并且在启动前需要有效的sitemap XML、sitemap索引或robots.txt引用时,请使用sitemap。这是一个发布构件技能,而不是爬虫或SEO平台。
-
app.Any("/path", handler)会覆盖所有动词,包括合法的GET/POST,必须手动转发,极易出错 -
app.OnErrorCode(404)是兜底机制,无法区分“路径不存在”和“动词不支持”,且触发时响应头已部分写出,StatusCode(405)可能失效 - Iris 的
405响应默认带Allowheader(如Allow: GET, POST),而OnErrorCode无法自动推导这个值
额外注意:OPTIONS 预检请求的处理
CORS 场景下浏览器会发 OPTIONS 请求,如果你没显式注册 app.Options,Iris 默认不会返回 200 或 Allow 头,可能导致预检失败。
建议统一加一条:
app.Options("/{any:path}", func(ctx iris.Context) {
ctx.Header("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,PATCH,OPTIONS")
ctx.Header("Access-Control-Allow-Headers", "Content-Type,Authorization")
ctx.StatusCode(200)
})
这条必须放在 UseRouter 拦截逻辑之后,否则会被当成“非法动词”拦截掉。顺序错了,CORS 就崩。
真正的难点不在写拦截逻辑,而在厘清 Iris 路由阶段(router lookup → middleware → handler)与各注册 API(Use / UseRouter / Any / Options)的执行时机。漏掉一个时序,拦截就形同虚设。


















