知我者谓我心忧,不知我者谓我何求,悠悠苍天,此何人哉
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package mainimport ( "net/http" ) func main () { http.HandleFunc("/" , foo) http.ListenAndServe(":3000" , nil ) } func foo (w http.ResponseWriter, r *http.Request) { w.Header().Set("Server" , "A Go Web Server" ) w.WriteHeader(200 ) }
Rendering Plain Text 1 2 3 4 5 6 7 8 9 10 11 12 13 14 package mainimport ( "net/http" ) func main () { http.HandleFunc("/" , foo) http.ListenAndServe(":3000" , nil ) } func foo (w http.ResponseWriter, r *http.Request) { w.Write([]byte ("OK" )) }
Rendering JSON 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package mainimport ( "encoding/json" "net/http" ) type Profile struct { Name string Hobbies []string } func main () { http.HandleFunc("/" , foo) http.ListenAndServe(":3000" , nil ) } func foo (w http.ResponseWriter, r *http.Request) { profile := Profile{"Alex" , []string {"snowboarding" , "programming" }} js, err := json.Marshal(profile) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type" , "application/json" ) w.Write(js) }
Rendering XML 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package mainimport ( "encoding/xml" "net/http" ) type Profile struct { Name string Hobbies []string `xml:"Hobbies>Hobby"` } func main () { http.HandleFunc("/" , foo) http.ListenAndServe(":3000" , nil ) } func foo (w http.ResponseWriter, r *http.Request) { profile := Profile{"Alex" , []string {"snowboarding" , "programming" }} x, err := xml.MarshalIndent(profile, "" , " " ) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type" , "application/xml" ) w.Write(x) }
Serving a File 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package mainimport ( "net/http" "path" ) func main () { http.HandleFunc("/" , foo) http.ListenAndServe(":3000" , nil ) } func foo (w http.ResponseWriter, r *http.Request) { fp := path.Join("images" , "foo.png" ) http.ServeFile(w, r, fp) }
Important: http.ServeFile() does not automatically sanitize the file path. So if you’re constructing a file path from untrusted user input, you must sanitize the input with filepath.Clean() before using it to avoid directory traversal attacks.
Rendering a HTML Template 1 2 3 4 File: templates/index.html <h1>Hello {{ .Name }}</h1> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package mainimport ( "html/template" "net/http" "path" ) type Profile struct { Name string Hobbies []string } func main () { http.HandleFunc("/" , foo) http.ListenAndServe(":3000" , nil ) } func foo (w http.ResponseWriter, r *http.Request) { profile := Profile{"Alex" , []string {"snowboarding" , "programming" }} fp := path.Join("templates" , "index.html" ) tmpl, err := template.ParseFiles(fp) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if err := tmpl.Execute(w, profile); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } }
Rendering a HTML Template to a String Instead of passing in the http.ResponseWriter when executing your template (like in the above snippet) use a buffer instead:
1 2 3 4 5 6 7 ... buf := new (bytes.Buffer) if err := tmpl.Execute(buf, profile); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } templateString := buf.String() ...
Using Layouts and Nested Templates File: templates/layout.html
1 2 3 4 5 6 7 8 <html > <head > <title > {{ template "title" . }}</title > </head > <body > {{ template "content" . }} </body > </html >
File: templates/index.html
1 2 3 4 5 6 {{ define "title" }}An example layout{{ end }} {{ define "content" }} <h1 > Hello {{ .Name }}</h1 > <p > Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p > {{ end }}
File: main.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 package mainimport ( "html/template" "net/http" "path" ) type Profile struct { Name string Hobbies []string } func main () { http.HandleFunc("/" , foo) http.ListenAndServe(":3000" , nil ) } func foo (w http.ResponseWriter, r *http.Request) { profile := Profile{"Alex" , []string {"snowboarding" , "programming" }} lp := path.Join("templates" , "layout.html" ) fp := path.Join("templates" , "index.html" ) tmpl, err := template.ParseFiles(lp, fp) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if err := tmpl.Execute(w, profile); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } }
https://www.alexedwards.net/blog/golang-response-snippets