這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
目錄 [−]
- 只發送header
- 返回普通文本
- 返回JSON資料
- 返回XML資料
- 檔案服務
- 使用HTML模版
- 使用HTML模板產生字串
- 使用嵌套的模版
原文: HTTP Response Snippets for Go by Alex Edwards.
受 Rails layouts and rendering啟發, 我覺得寫一個關於Go HTTP Response的程式碼片段集合是一個不錯的主意, 它可以用來說明Go web應用程式中通用的HTTP Response的使用。
只發送header
123456789101112131415 |
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)} |
測試:
12345 |
$ curl -i localhost:3000HTTP/1.1 200 OKServer: A Go Web ServerContent-Type: text/plain; charset=utf-8Content-Length: 0 |
返回普通文本
1234567891011121314 |
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"))} |
測試:
123456 |
$ curl -i localhost:3000HTTP/1.1 200 OKContent-Type: text/plain; charset=utf-8Content-Length: 2OK |
返回JSON資料
1234567891011121314151617181920212223242526272829 |
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)} |
測試:
123456 |
$ curl -i localhost:3000HTTP/1.1 200 OKContent-Type: application/jsonContent-Length: 56{"Name":"Alex",Hobbies":["snowboarding","programming"]} |
返回XML資料
1234567891011121314151617181920212223242526272829 |
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)} |
測試:
123456789101112 |
$ curl -i localhost:3000HTTP/1.1 200 OKContent-Type: application/xmlContent-Length: 128<Profile> <Name>Alex</Name> <Hobbies> <Hobby>snowboarding</Hobby> <Hobby>programming</Hobby> </Hobbies></Profile> |
檔案服務
1234567891011121314151617 |
package mainimport ( "net/http" "path")func main() { http.HandleFunc("/", foo) http.ListenAndServe(":3000", nil)}func foo(w http.ResponseWriter, r *http.Request) { // Assuming you want to serve a photo at 'images/foo.png' fp := path.Join("images", "foo.png") http.ServeFile(w, r, fp)} |
測試:
123456 |
$ curl -I localhost:3000HTTP/1.1 200 OKAccept-Ranges: bytesContent-Length: 236717Content-Type: image/pngLast-Modified: Thu, 10 Oct 2013 22:23:26 GMT |
使用HTML模版
模板檔案:templates/index.html
templates/index.html
12 |
<h1>Hello { { .Name } }</h1><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p> |
1234567891011121314151617181920212223242526272829303132 |
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) }} |
測試:
1234567 |
$ curl -i localhost:3000HTTP/1.1 200 OKContent-Type: text/html; charset=utf-8Content-Length: 84<h1>Hello Alex</h1><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p> |
使用HTML模板產生字串
除了上面的把http.ResponseWriter
作為模版的執行參數,還可以使用buffer得到渲染的結果。
1234567 |
...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
12345678 |
<html> <head> <title>{ { template "title" . } } </title> </head> <body { { template "content" . } } </body></html> |
檔案:templates/index.html
templates/index.html
123456 |
{ { define "title" } }An example layout{ { end } }{ { define "content" } }<h1>Hello { { .Name } }</h1><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>{ { end } } |
1234567891011121314151617181920212223242526272829303132333435 |
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") // Note that the layout file must be the first parameter in ParseFiles 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) }} |
測試:
1234567891011121314 |
$ curl -i localhost:3000HTTP/1.1 200 OKContent-Type: text/html; charset=utf-8Content-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> |