允许的内容类型超过:大猩猩中的application / json

时间:2019-06-05 02:48:45

标签: go

使用出色的Gorilla mux,我有一个特殊的处理程序,用于使用application / json作为内容类型的API请求:

apiRouter := router.PathPrefix("/api").Headers("Content-Type", "application/json").Subrouter()

但是,有些用户喜欢提供的不仅仅是字符串,即application / json;。 charset = UTF-8。设置此标头值后,处理程序将返回404。

通过允许json和任何字符集规范来处理此问题的最佳方法是什么?

3 个答案:

答案 0 :(得分:2)

使用正则表达式的其他答案匹配任何字符集或更糟的甚至是 application/jsonfooo 之类的字符集。如果你想更严格,你可以使用匹配器函数:

func matchJSON(r *http.Request, rm *mux.RouteMatch) bool {
    ctHdr := r.Header.Get("Content-Type")
    contentType, params, err := mime.ParseMediaType(ctHdr)
    if err != nil {
        return false
    }
    charset := params["charset"]
    return contentType == "application/json" && (charset == "" || strings.EqualFold(charset, "UTF-8"))
}

然后,像这样使用它:

router.PathPrefix("/api").MatcherFunc(matchJSON)

答案 1 :(得分:0)

我认为这是HeadersRegexp的好用例。

来自the Go Doc

正则表达式支持还用于匹配路由内的标题。例如,我们可以这样做:

r.HeadersRegexp("Content-Type", "application/(text|json)")

...,并且该路由将同时匹配内容类型为application/jsonapplication/text的两个请求

答案 2 :(得分:0)

这是我的做法:

apiRouter := router.PathPrefix("/api").HeadersRegexp("Content-Type", fmt.Sprintf("%s.*", MIMEApplicationJSON)).Subrouter()

请记住,您可以在实际端点而不是在根级别应用路由。对于GET请求,无需指定Content-Type,但对于POST,则应检查一个。