我编写了一个REST API服务,要求所有响应都是JSON。但是,当Go http请求解析器遇到错误时,它会返回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
请注意无效的Authorization标头。当然,400是正确的回应,但当然是文本/简单。有没有办法配置Go http解析器使用自定义错误响应媒体类型和主体?
答案 0 :(得分:3)
你做不到。您可以在net / http源中找到它,只有在请求格式错误时才会发生:
https://github.com/golang/go/blob/master/src/net/http/server.go#L1744
我认为您的问题可能是您在curl中添加的标题中的新行?
您将能够使用json响应401,403,404,500个错误,但在server.go中处理错误的请求或错误的标头(太长,格式错误)。目前没有办法拦截这些错误,虽然它位于consideration之下,所以你唯一的解决办法就是修补stdlib源码(我不建议这样做)。但是,由于此错误仅在客户端出错并且请求格式错误时才出现,因此可能不是一个大问题。文本响应的原因是浏览器或类似客户端(如没有-v的curl)不会只看到空响应。你可以在你的应用程序前放置像nginx这样的代理,但是你永远不会看到请求,因为它是一个错误的请求,你的代理会处理它。
如果你设置一个特定的静态错误页面为它服务400个错误并提供你指定的400.json文件,你可能会在前面使用像nginx这样的代理吗?这是我能想到的唯一解决方案。像这样的指令可能适用于nginx:
error_page 400 /400.json;
如果您希望能够自定义这些错误,可以在链接的问题上添加注释,让他们知道您遇到了这个特定问题。
答案 1 :(得分:-1)
如果您使用的是标准网络/ http库,则可以使用以下代码。看一下我从
获得这个例子的答案Showing custom 404 error page with standard http package @Mostafafunc 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
}
}