我修改了this tutorial的中间件|检查所有 PUT 和 POST 请求的 JSON MIME 类型。
但是中间件似乎每次都以“不支持媒体类型”作为响应。我在下面尝试了 curl 命令,我在其中明确设置了正确的 MIME 类型。我打印每个请求客户端的 Content-Type header 字段,该字段始终为“text/plain;charset=utf-8”。
中间件:
func EnforceJSON(h httprouter.Handle) httprouter.Handle {
return func(rw http.ResponseWriter, req *http.Request, ps httprouter.Params) {
// Check the existence of a request body
if req.ContentLength == 0 {
http.Error(rw, http.StatusText(400), http.StatusBadRequest)
return
}
// Check the MIME type
buf := new(bytes.Buffer)
buf.ReadFrom(req.Body)
// Prints "text/plain; charset=utf-8"
fmt.Println(http.DetectContentType(buf.Bytes()))
if http.DetectContentType(buf.Bytes()) != "application/json; charset=utf-8" {
http.Error(rw, http.StatusText(415), http.StatusUnsupportedMediaType)
return
}
h(rw, req, ps)
}
}
...
router.POST("/api/v1/users", EnforceJSON(CreateUser))
我的 curl 命令:
curl -H "Content-Type: application/json; charset=utf-8" \
-X POST \
-d '{"JSON": "Will be checked after the middleware accepted the MIME type."}' \
http://localhost:8080/api/v1/users
或者我试过Postman但结果是一样的。
最佳答案
查看 DetectContentType 函数的实现,它们遵循“MIME 嗅探”指南 (https://mimesniff.spec.whatwg.org/) 中描述的规则。
要根据内容确定 MIME 类型,此特定函数使用项 “7. 确定资源的计算 MIME 类型”。该项目没有确定 'application/json' 类型,遵循这些规则将导致 'text/plain' MIME 类型。
这在 DetectContentType 实现 (https://golang.org/src/net/http/sniff.go) 第 252 行的函数 match 中可见。
关于api - Go - 中间件阻止每个请求的 MIME 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30310046/