golang返回json等格式数据

知我者谓我心忧,不知我者谓我何求,悠悠苍天,此何人哉

Sending Headers Only

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main

import (
"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 main

import (
"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 main

import (
"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 main

import (
"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 main

import (
"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)
}

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 main

import (
"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 main

import (
"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)
}
}

https://www.alexedwards.net/blog/golang-response-snippets