为了账号安全,请及时绑定邮箱和手机立即绑定

如果已设置标头,如何使用自定义 http 处理程序/中间件?

如果已设置标头,如何使用自定义 http 处理程序/中间件?

Go
尚方宝剑之说 2021-09-10 15:05:21
我试图在 go 中链接 HTTP 处理程序以提供一些附加功能,如下所示:package routerimport (    // snip    "github.com/gorilla/mux"    "github.com/gorilla/handlers"    "net/http")// snipr := mux.NewRouter()/* routing code */var h http.Handlerh = rif useGzip {    h = handlers.CompressHandler(h)}if useLogFile {    fn := pathToLog    accessLog, err := os.OpenFile(fn, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)    if err != nil {        panic(err)    }    h = handlers.CombinedLoggingHandler(accessLog, h)}// etc...问题是,如果任何HTTP头已经由一个控制器设置大猩猩/ MUX路由器点(例如,w.WriteHeader(404)或w.Header().Set("Content-Type", "application/json")) -此默默休息的任何“包装”处理程序试图设置或添加自己的头,像压缩处理程序。我看不到任何错误,除非我忘记在某处捕获错误,但浏览器收到无效响应。有没有什么优雅的方法来处理这个问题,除了将标题藏在某处然后让最终处理程序编写它们之外?这似乎意味着重写处理程序的代码,如果可能的话,我很想避免这样做。
查看完整描述

2 回答

?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

一旦您调用w.WriteHeader(404),标题就会连接到电线上。所以你不能再添加它了。最好的方法是缓冲状态代码并将其写入链的末尾。

例如,您可以提供自己的包装器,http.ResponseWriter以便重新实现WriteHeader()以保存状态值。然后添加方法Commit()来实际编写它。调用Commit()最后一个处理程序。当然,您必须以某种方式确定最后一个处理程序。


查看完整回答
反对 回复 2021-09-10
?
慕田峪4524236

TA贡献1875条经验 获得超5个赞

我经历了同样的默默失败的行为。但仅在我使用 WritheHeader 设置 StatusOK 以外的状态代码的处理程序中。我认为 CompressHandler 的这一部分出了问题:


if h.Get("Content-Type") == "" {

    h.Set("Content-Type", http.DetectContentType(b))

}

在我自己的处理程序中显式设置内容类型时,这似乎已解决:


w.Header().Set("Content-Type", "text/html; charset=utf-8")

w.WriteHeader(code)


查看完整回答
反对 回复 2021-09-10
  • 2 回答
  • 0 关注
  • 165 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信