Go JSON响应被追加到HTML模板输出中

Go JSON响应被追加到HTML模板输出中,go,go-gin,Go,Go Gin,我有一种奇怪的行为,我认为这是由于使用冲突的基础设施造成的: 反向代理的Traefik 内部库SM,它将所有请求封装到我们的后端语言中;它解析请求中的JSON,并为响应返回特定的JSON结构 对于Traefik,我必须返回HTML页面而不是JSON 我使用GoforBe并为FE呈现HTML模板 我的流程看起来有点像这样: func (r RestrictedHandler) Exec(c *smContext) (interface{}, ServiceError) { // check

我有一种奇怪的行为,我认为这是由于使用冲突的基础设施造成的:

  • 反向代理的Traefik
  • 内部库SM,它将所有请求封装到我们的后端语言中;它解析请求中的JSON,并为响应返回特定的JSON结构
  • 对于Traefik,我必须返回HTML页面而不是JSON
  • 我使用GoforBe并为FE呈现HTML模板 我的流程看起来有点像这样:

    func (r RestrictedHandler) Exec(c *smContext) (interface{}, ServiceError) {
        // check if we have a cookie for auth
        if tokenCookie, err := tokens.GetTokenFromCookie(c); err != nil {
            c.HTML(401, "login.html")
            return "", err
        } else {
            return r, nil
        }
    }
    
    这个的包装是:

        if response, err := newH1.Exec(hc); err != nil {
            c.JSON(err.GetStatusCode(), gin.H{
                "status": "error",
                "error": err
            })
        } else {
            c.JSON(http.StatusOK, gin.H{
                "status": "success",
                "data": response
            })
        }
    
    因此,这里发生的事情(我怀疑)是,我将HTML文本和JSON文本“推”到响应“缓冲区”,从而导致用户获得以下HTML页面:

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <title>Title</title>
      </head>
      <body>
        My returned page
       </body>
    </html>{"status":"error","error":{"msg":"Unauthorized error","type":"Unauthorized"}}
    
    
    标题
    我返回的页面
    {“status”:“error”,“error”:{“msg”:“Unauthorized error”,“type”:“Unauthorized”}
    
    所以我的问题是,如何停止在c.HTML()之后写入上下文

  • 我尝试了c.Next()和c.Abort(),但我想它们更适合链接中间件
  • 更改SM库代码(与我的同事共享代码,但仍然可以提交拉取请求),以某种方式检查“如果响应中有html标记,请不要执行c.JSON()”

  • 所以我和我们SM图书馆的负责人谈过。我们向上下文对象添加了一个标志,称为“responseOverrided”。任何引用上下文对象的人都可以设置该标志(在他自己的服务中),然后在SM库中,如果设置了该标志,我们就不会返回JSON:

    // someService.go
    func (r RestrictedHandler) Exec(c *smContext) (interface{}, ServiceError) {
    // check if we have a cookie for auth
    if tokenCookie, err := tokens.GetTokenFromCookie(c); err != nil {
        c.HTML(401, "login.html")
        c.replyOverriden = true
        return "", err
    } else {
        return r, nil
    }
    
    }

    在库代码中:

     // SM.go
     response, err := newH1.Exec(hc);
     if !hc.responseOverridden {
         err != nil {
            c.JSON(err.GetStatusCode(), gin.H{
              "status": "error",
              "error": err
            })
         } else {
            c.JSON(http.StatusOK, gin.H{
              "status": "success",
              "data": response
            })
         }
     } 
     // someone probably handled something in hc, so don't return JSON   
    

    若不是
    'application/json'
    ,您可以尝试读取响应的内容类型,而不添加json值
    c.Writer.Header().Get(“内容类型”)
    是您读取内容类型的方式。希望对你有用。