• 作成:

JavaScriptのデータ通信, form, fetchとFormData

JavaScriptでデータ通信する時に最近考えることが多いのでメモしておこうかなと思います.

formにデータを突っ込んでsubmitする

formを取り出してsubmitメソッドを呼び出す方法.

formに既に入っている情報で足りない時はinput要素をformに足してやります.

const element = document.createElement("input");
element.name = name;
element.value = value;
form.appendChild(element);

もともとフレームワークがformにCSRF対策のtokenとか入れてると面倒が少ない. formベースで作っておくとJavaScript使わない方式にも変えやすい.

formの送信先がredirect先を指定している場合に自動でリダイレクトしてくれる.

送信後のページの再読み込みが自動で行われる.

FormDataを生成してfetchする

ページを最読み込みさせてはいけない場合(入力中の<textarea>の内容を保持したままにしたいとか)はformsubmitしてはいけないのでfetchなどを使う.

その際FormDataを使うと便利. FormData - Web API インターフェイス | MDN

new FormData(form)のようにformをFormDataに突っ込んであげるとそれに合ったFormDataを生成してくれる.

ユーザにForm上で入力してもらってデータを生成出来るのも良いし, フレームワークがformに埋め込んだtokenとかも送信してくれるのでYesodとか使ってても特別なことをしなくていい.

認証した状態で通信したい場合はcredentials: "same-origin"を追加しましょう.(よく忘れる)

fetch(form.action, {
    method: "post",
    headers: { "accept": "application/json" },
    body: new FormData(form),
    credentials: "same-origin"
}).then(response => {
    if (response.ok) {
        form.reset();
    }
    else {
        throw response;
    }
}).catch(err => {
    form.reset();
    alert(err);
    throw err;
});

エラーキャッチをrespose.okcatch両方でやらないといけないのが面倒くさい. 何故こんな仕様になったんだろう.

ユーザが入力した情報で足りない時にはFormDataappend(name, value)メソッドを使います.

fetchのpolyfill

IEはfetchに対応していない.(575) Can I use... Support tables for HTML5, CSS3, etc

なのでIE対応させたい場合は以下の2つのpolyfillを追加しておきましょう. どちらもcdnjs.com - The best FOSS CDN for web related libraries to speed up your websites!で読み込めます.

本当に動くかどうかはIE使ってないので知りません.

XMLHttpRequest

現在のfetchはアップロード状態を取得できないため, アップロード時にプログレスバーを表示したい場合などはサーバサイドにAPIを追加するか, XMLHttpRequestを使うしかない.多分.

幸いにもまだそんな案件にはぶち当たっていません.(仕様を捻じ曲げて回避)