gopherjs xhr 學習

gopherjs 生態裏有 XMLHttpRequest 的包裝 honnef.co/go/js/xhr 庫(項目地址文檔javascript

XMLHttpReqeust 文檔html

例子

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

POST 方法發送 json 的例子

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

相關文章
相關標籤/搜索