gopherjs xhr 学习

Deadly 提交于 2019-11-30 08:16:55

gopherjs 生态里有 XMLHttpRequest 的包装 honnef.co/go/js/xhr 库(项目地址文档

XMLHttpReqeust 文档

例子

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 方法发送请求。

定义 Reply 结构,内嵌 *js.Object 字段,Header 字段加上 tag `js:"header"`, 再用 &Reply{Object: req.Response} 包装响应结果对象,这样就能用 go 的简洁语法访问内嵌的 js.Object。

更复杂些的例子

获取 http://httpbin.org/json 返回的 json 然后解析,当前返回的 json 是:

{
  "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 代码:

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 相比来判断。

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 的体积。

调用 req.SetRequestHeader 方法设置请求头 Content-Type 为 application/json。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!