首页 > 解决方案 > 更改 Gin 中间件中的 Content-Type 标头

问题描述

我设置了一个自定义 gin 中间件来处理错误,但是,它确实更改了Content-Type标题。

package middleware

import (
    "fmt"
    "net/http"

    "github.com/gin-gonic/gin"
    "github.com/go-playground/validator/v10"
)

func validationErrorToText(e validator.FieldError) string {
    switch e.Tag() {
    case "required":
        return fmt.Sprintf("%s is required", e.Field())
    case "max":
        return fmt.Sprintf("%s cannot be longer than %s", e.Field(), e.Param())
    case "min":
        return fmt.Sprintf("%s must be longer than %s", e.Field(), e.Param())
    case "email":
        return fmt.Sprintf("Invalid email format")
    case "len":
        return fmt.Sprintf("%s must be %s characters long", e.Field(), e.Param())
    }
    return fmt.Sprintf("%s is not valid", e.Field())
}

func Errors() gin.HandlerFunc {
    return func(c *gin.Context) {
        c.Next()
        // Only run if there are some errors to handle
        if len(c.Errors) > 0 {
            for _, e := range c.Errors {
                // Find out what type of error it is
                switch e.Type {
                case gin.ErrorTypePublic:
                    // Only output public errors if nothing has been written yet
                    if !c.Writer.Written() {
                        c.JSON(c.Writer.Status(), gin.H{"error": e.Error()})
                    }
                case gin.ErrorTypeBind:
                    errs := e.Err.(validator.ValidationErrors)
                    list := make(map[int]string)

                    for field, err := range errs {
                        list[field] = validationErrorToText(err)
                    }
                    // Make sure we maintain the preset response status
                    status := http.StatusBadRequest
                    if c.Writer.Status() != http.StatusOK {
                        status = c.Writer.Status()
                    }
                    c.Header("Content-Type", "application/json")
                    c.JSON(status, gin.H{
                        "status": "error",
                        "errors": list,
                    })

                default:
                    c.JSON(http.StatusBadRequest, gin.H{"errors": c.Errors.JSON()})
                }
            }
        }
    }
}

text/plain; charset=utf-8在响应Content-Type标头中得到了一个。

标签: gogo-gin

解决方案


将此代码c.Header("Content-Type", "application/json")作为函数体的第一行func(c *gin.Context) {...}

问题是这个包 gin 甚至在你调用 c.JSON 函数之前就在内部改变了标题。这就是问题所在。


推荐阅读