简体   繁体   English

多个响应.WriteHeader调用

[英]Multiple response.WriteHeader calls

I am new to go and have difficulty rendring templates. 我是新手,很难重新模板。

Here is my functions that are to generate template: 这是我要生成模板的功能:

base.html base.html文件

//Render templates for the given name, template definition and data object
func renderTemplate(w http.ResponseWriter, name string, template string, viewModel interface{}) {
    // Ensure the template exists in the map.
    tmpl, ok := templates[name]
    if !ok {
        http.Error(w, "The template does not exist.", http.StatusInternalServerError)
    }
    err := tmpl.ExecuteTemplate(w, template, viewModel)
    if err != nil {
    log.Printf("temlate error here")
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}


 func EditNote(w http.ResponseWriter, r *http.Request) {
    //var viewModel models.EditChnl
    vars := mux.Vars(r)
    //ch := bson.M{"id": "Ale"}
    title := vars["title"]
    log.Printf("%v\n", title)
    session, err := mgo.Dial("localhost")
    if err != nil {
      panic(err)
    }
        defer session.Close()
        session.SetMode(mgo.Monotonic, true)
        c := session.DB("tlgdb").C("chnls")
        log.Printf("title is %s \n", title)
        var result  []models.Chnl
        err = c.Find(bson.M{"title": "xxx"}).All(&result)
        log.Printf("%v\n", result)

        if err != nil {
          log.Printf("doc not found")
          log.Fatal(err)
          return
        }
    renderTemplate(w, "edit", "base", result)
}

And here are the templates: 这是模板:

{{define "base"}}
<html>
  <head>
    {{template "head" .}}
  </head>
  <body>

    {{template "body" .}}

  </body>
</html>
{{end}}

edit.thml edit.thml

{{define "head"}}<title>Edit Note</title>{{end}}
{{define "body"}}
<h1>Edit Note</h1>
<form action="/chnls/update/{{.Title}}" method="post">
<p>Title:<br> <input type="text" value="{{.Title}}" name="title"></p>
<p>Description:<br> <textarea rows="4" cols="50" name="description">{{.Description}}</textarea> </p>
<p><input type="submit" value="submit"/></p>
</form>
{{end}}

The objects to render are: 要渲染的对象是:

type Chnl struct {
    Id    bson.ObjectId `json:"id"  bson:"_id,omitempty"`
    Title       string
    Description string
    CreatedOn   time.Time
    Creator     string
    Visits  int
    Score       int
}

The object that I'm trying to render exists in mongodb and I can print it out in console: 我要渲染的对象存在于mongodb中,可以在控制台中将其打印出来:

[{ObjectIdHex("56cc4493bc54f4245cb4d36b") sometitle blabla 2016-02-23 12:37:55.972 +0100 CET blabla 0 0}]

However I get this error: 但是我得到这个错误:

temlate error here
http: multiple response.WriteHeader calls

I'm wondering what is wrong here and how to fix it? 我想知道这里有什么问题以及如何解决?

The root problem is that you pass a slice of Chnl to the template: 根本问题是您将Chnl传递给模板:

var result  []models.Chnl
// ...
renderTemplate(w, "edit", "base", result)

And inside renderTemplate() param value of viewModel will be result . 而且里面renderTemplate()的参数值的方式viewModel将是result

And in your templates you refer to fields of the dot like if it would be a Chnl value and not a slice of it: {{.Title}} . 在模板中,您引用点的字段,例如它是否为Chnl值而不是其一部分: {{.Title}} So the first attempt to resolve it will fail. 因此,首次尝试解决该问题将失败。

Logging the errors is useful, so change your logging to also print the actual error, not just a generic error: 记录错误非常有用,因此请更改记录以打印实际错误,而不仅仅是一般错误:

log.Printf("Temlate error here: %v", err)

Which results in: 结果是:

2016/02/24 14:57:09 Temlate error here: template: edit.html:4:30: executing "body" at <.Title>: can't evaluate field Title in type []main.Chnl 2016/02/24 14:57:09此处出现Temlate错误:模板:edit.html:4:30:在<.Title>处执行“ body”:无法评估类型为[] main.Chnl的字段Title

I think you just want to pass 1 Chnl value and not a slice of them. 我认为您只想传递1 Chnl值,而不是其中的一小部分。 In EditNote() : EditNote()

if len(result) > 0 {
    renderTemplate(w, "edit", "base", result[0])
}

Next, know that http.Error() writes content to the response. 接下来,知道http.Error()将内容写入响应。 This means you cannot write further header values to the response. 这意味着您无法将更多的标头值写入响应。 Usually when you call http.Error() in your handler, you should return without doing anything with the response: 通常,当您在处理程序中调用http.Error()时,应该不做任何响应就返回:

if !ok {
    http.Error(w, "The template does not exist.", http.StatusInternalServerError)
    return // NOTE THIS RETURN
}

Similarly, after all your http.Error() call insert a return . 同样,在所有http.Error()调用之后,插入return You may do some cleanup, but response should not be touched after http.Error() . 您可以进行一些清理,但是不应在http.Error()之后触及响应。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM