目录 [−]
原文: HTTP Response Snippets for Go by Alex Edwards .
受 Rails layouts and rendering 启发, 我觉得写一个关于Go HTTP Response的代码片段集合是一个不错的主意, 它可以用来说明Go web应用程序中通用的HTTP Response的使用。
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 ) }
测试:
1 2 3 4 5 $ curl -i localhost:3000 HTTP/1.1 200 OK Server: A Go Web Server Content-Type: text/plain; charset=utf-8 Content-Length: 0
返回普通文本 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" )) }
测试:
1 2 3 4 5 6 $ curl -i localhost:3000 HTTP/1.1 200 OK Content-Type: text/plain; charset=utf-8 Content-Length: 2 OK
返回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) }
测试:
1 2 3 4 5 6 $ curl -i localhost:3000 HTTP/1.1 200 OK Content-Type: application/json Content-Length: 56 {"Name" :"Alex" ,Hobbies":[" snowboarding"," programming"]}
返回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) }
测试:
1 2 3 4 5 6 7 8 9 10 11 12 $ curl -i localhost:3000 HTTP/1.1 200 OK Content-Type: application/xml Content-Length: 128 <Profile> <Name>Alex</Name> <Hobbies> <Hobby>snowboarding</Hobby> <Hobby>programming</Hobby> </Hobbies> </Profile>
文件服务 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) }
测试:
1 2 3 4 5 6 $ curl -I localhost:3000 HTTP/1.1 200 OK Accept-Ranges: bytes Content-Length: 236717 Content-Type: image/png Last-Modified: Thu, 10 Oct 2013 22:23:26 GMT
使用HTML模版 模板文件:templates/index.html
templates/index.html 1 2 <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) } }
测试:
1 2 3 4 5 6 7 $ curl -i localhost:3000 HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Content-Length: 84 <h1>Hello Alex</h1> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
使用HTML模板生成字符串 除了上面的把http.ResponseWriter作为模版的执行参数,还可以使用buffer得到渲染的结果。
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() ...
使用嵌套的模版 文件:templates/layout.html
templates/layout.html 1 2 3 4 5 6 7 8 <html > <head > <title > { { template "title" . } } </title > </head > <body { { template "content " . } } </body > </html >
文件:templates/index.html
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 } }
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) } }
测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 $ curl -i localhost:3000 HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Content-Length: 180 <html> <head > <title>An example layout</title> </head> <body> <h1>Hello Alex</h1> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p> </body> </html>