如何为解析错误自定义 HTTP 400 响应?

How can I customize HTTP 400 responses for parse errors?

我编写了一个 REST API 服务,要求所有响应都是 JSON。但是,当 Go HTTP 请求解析器遇到错误时,它会 returns 400 作为纯文本响应,而不会调用我的处理程序。示例:

> curl -i -H 'Authorization: Basic hi    
there' 'http://localhost:8080/test' -v
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /test HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
> Authorization: Basic hi
> there
> 
< HTTP/1.1 400 Bad Request
HTTP/1.1 400 Bad Request
< Content-Type: text/plain; charset=utf-8
Content-Type: text/plain; charset=utf-8
< Connection: close
Connection: close

< 
* Closing connection 0

注意无效授权 header。当然 400 是正确的响应,但它当然是 text/plain。有什么方法可以配置 Go http 解析器以使用自定义错误响应媒体类型和正文?

如果您使用的是标准 net/http 库,则可以使用以下代码。看看这个答案 我从

得到这个例子
func homeHandler(w http.ResponseWriter, r *http.Request) {
    if r.URL.Path != "/" {
        errorHandler(w, r, http.StatusNotFound)
        return
    }
    fmt.Fprint(w, "welcome home")
}

func errorHandler(w http.ResponseWriter, r *http.Request, status int) {
    w.WriteHeader(status)
    if status == http.StatusNotFound {
        // JSON Out here
    }
}

你不能。您可以在 net/http 来源中找到它,只有在请求格式错误时才会发生:

https://github.com/golang/go/blob/master/src/net/http/server.go#L1744

我认为您的问题可能是 header 您在 curl 中添加的新行?

401、403、404、500 错误您可以用 json 响应,但错误的请求或错误的 header(太长,格式错误)在 server.go.

虽然在consideration下,但目前没有办法拦截此类错误,因此您唯一的解决方案是修补 stdlib 源(我不建议这样做)。但是,由于此错误仅在客户端出错且请求格式错误时才会出现,因此这可能不是什么大问题。文本响应的原因是浏览器或类似客户端(如没有 -v 的 curl)不会只看到空响应。你可以在你的应用程序前面放置一个像 nginx 这样的代理,但是你永远不会看到请求,因为它是一个错误的请求,你的代理会处理它。

如果您设置一个特定的静态错误页面来为 400 错误提供服务并提供您指定的 400.json 文件,那么您可能可以在前面使用像 nginx 这样的代理来做到这一点?这是我能想到的唯一解决方案。类似这样的指令可能适用于 nginx:

error_page 400 /400.json;

如果您希望能够自定义这些错误,或许可以在链接的问题中添加评论,让他们知道您遇到了这个特定问题。