gopherjs 生态里有 XMLHttpRequest 的包装 honnef.co/go/js/xhr 库(项目地址, 文档)javascript
package main import ( "github.com/gopherjs/gopherjs/js" "honnef.co/go/js/xhr" ) type Reply struct { *js.Object Headers map[string]string `js:"headers"` } func main() { req := xhr.NewRequest("GET", "http://httpbin.org/get") req.ResponseType = "json" err := req.Send(nil) if err != nil { println("err:", err) return } if req.Status != 200 { println("err:", req.StatusText) return } println(req.Response) reply := &Reply{Object: req.Response} ua := reply.Headers["User-Agent"] println("UA:", ua) }
经过 xhr.NewRequest 建立出 *xhr.Request
对象,设置响应类型 ResponeType 为 "json",这样响应结果若是是 JSON 字符串就能被自动解析为 object。调用 Send 方法发送请求。java
定义 Reply 结构,内嵌 *js.Object
字段,Header 字段加上 tag `js:"header"`, 再用 &Reply{Object: req.Response}
包装响应结果对象,这样就能用 go 的简洁语法访问内嵌的 js.Object。git
获取 http://httpbin.org/json 返回的 json 而后解析,当前返回的 json 是:github
{ "slideshow": { "author": "Yours Truly", "date": "date of publication", "slides": [ { "title": "Wake up to WonderWidgets!", "type": "all" }, { "items": [ "Why <em>WonderWidgets</em> are great", "Who <em>buys</em> WonderWidgets" ], "title": "Overview", "type": "all" } ], "title": "Sample Slide Show" } }
go 代码:json
package main import ( "github.com/gopherjs/gopherjs/js" "honnef.co/go/js/xhr" ) type SlideShow struct { *js.Object Author string `js:"author"` Date string `js:"date"` Slides []*Slide `js:"slides"` Title string `js:"title"` } type Slide struct { *js.Object Title string `js:"title"` Type string `js:"type"` Items []string `js:"items"` } func getJson() error { req := xhr.NewRequest("GET", "http://httpbin.org/json") req.ResponseType = "json" err := req.Send(nil) if err != nil { return err } println(req.Response) println(req.Status, req.StatusText) slideShow := &SlideShow{Object: req.Response.Get("slideshow")} println("author:", slideShow.Author) for i, slide := range slideShow.Slides { println(i, "title:", slide.Title) if slide.Get("items") != js.Undefined { for j, item := range slide.Items { println(" ", j, "item:", item) } } } return nil } func main() { err := getJson() if err != nil { println("err", err) } }
一样是把 js 对象包装到 go 结构(SlideShow)中处理,特别指出 json 的 .slideshow.slides[0]
是没有 items 字段的,须要与 js.Undefined 相比来判断。app
package main import ( "github.com/cathalgarvey/fmtless/encoding/json" "github.com/gopherjs/gopherjs/js" "honnef.co/go/js/xhr" ) func callPostAnything() error { req := xhr.NewRequest("POST", "http://httpbin.org/anything") req.ResponseType = "json" req.SetRequestHeader("Content-Type", "application/json") data, err := json.Marshal(js.M{"a": 1, "b": 2}) if err != nil { return err } err = req.Send(data) if err != nil { return err } println(req.Status) println(req.Response) return nil } func main() { err := callPostAnything() if err != nil { println("err", err) } }
这里使用 fmtless 库提供的 json 包来把对象 js.M 序列化为 JSON 字符串,没有使用标准库的 fmt 包,这样能够减少 gopherjs 生成的 js 的体积。less
调用 req.SetRequestHeader 方法设置请求头 Content-Type 为 application/json。dom