コンテンツへスキップ

GoではじめるWebAssebmly その4「POST系ネットワーク処理」

by : 2019/02/08

WebAssebmlyはWebブラウザ上でバイナリファイル(テキスト形式もあり)を実行できる環境です。JavaScriptと異なりコードの漏洩がなく、実行速度も高速というのがメリットです。

WebAssebmlyは元々Rustで開発することが多かったですが、最近では様々なプログラミング言語が対応しています。その一つがGoです。Go 1.11からWebAssembly向けにもコンパイルできるようになっています。

一般的なWebAssemblyはDOMやネットワーク操作が行えません。それに対してGo 1.11ではJavaScript APIを使えるようにした syscall/js パッケージを用いることで、DOMやネットワーク操作を可能にしています。

そこで今回はネットワーク処理(POST処理)の書き方を解説します。

使いどころ

POSTやPUT、DELETEはREST APIを扱うのに使われるでしょう。今回はPOSTリクエストでJSONを送信する方法を解説します。

ボタンを押したタイミングで処理

例えば今回はボタンを押したタイミングで入力されている内容をJSON化して送信します。そこでボタンのクリックイベントを設定します。

cb1 := js.NewCallback(func(args []js.Value) {
// この中に処理を書く
})
button.Call("addEventListener", "click", cb1)

view raw
index.go
hosted with ❤ by GitHub

goroutineに注意

ネットワーク処理は非同期なのでデータを安全に送受信するためにgoroutineが使われています。そして単純にPOST処理を書くと、WebAssebmly全体で設定しているgoroutineが終了してデッドロックが発生してしまいました。

そこで処理全体を無名関数化して、それをgoで実行(goroutine化)します。

go func() {
todo := document.Call("getElementById", "todo")
var value = todo.Get("value").String()
input, err := json.Marshal(Input{Todo: value})
res, err := http.Post(domain, "application/json", bytes.NewBuffer(input))
if err != nil {
log.Fatal(err)
} else {
addTodo(document, value)
}
defer res.Body.Close()
}()

view raw
index.go
hosted with ❤ by GitHub

via runtime: wasm: all goroutines asleep and no JavaScript callback pending – deadlock · Issue #26382 · golang/go

この問題は 1.12 で直る予定です。

CORSに注意

Goでhttp.Postを使っていますが、実際にはWebブラウザのメインスレッド側でリクエスト処理が行われます。CORSは通常のJavaScriptと変わらず行われます。また、ネットワーク接続内容などは開発者ツールで見られますので、隠蔽できる訳ではありません。


Goを使ったWebAssemblyは他の言語では見られないDOM操作とネットワークアクセスが可能です。これは大きなメリットと言えるでしょう。ぜひこの特徴を活用し、高速で安全なWebアプリケーションを開発してください。

From → HTML5

コメントは受け付けていません。

%d人のブロガーが「いいね」をつけました。