【JS】FormDataと戯れる

JavaScript

こんにちは、しきゆらです。

今日は、JavaScriptでフォームのデータを簡単に取得したり、XMLHttpRequestなどで送信しやすいFormDataオブジェクトに触れたら便利だったので、メモしておきます。

 

formタグのデータをJSで取得し、それに追加して他のデータを送りたい場合などはよくあると思います。

そんな時は、formの中にhiddenでinput要素を配置するとか、方法はいくつかあると思います。

でも、HTML的にはhiddenの要素は意味がないので、データの扱いはJSだけで完結していたいですよね。(個人的な意見です)

 

そこで使えるのがFormDataというもの。

formタグの中身をそのままkey, valueの組み合わせで表現できる魔法のようなオブジェクトです。

参考:FormData – MDN

簡単な使い方をまとめておきます。

 


 

FormDataの基本

form要素から作成する

基本的には、HTMLのform要素から作成します。

サンプルとして、以下のようなものを考えてみます。

<form id="form_element" name="test">
  <input type="text" name="user_name">
  <input type="passed" name="pass">
</form>

 

このform要素からFormDataを作るには、以下のとおり。

var form = document.getElementById("form_element");
var formdata = new FormData(form);

FormDataには、form要素を引数として渡して使います。

上記のHTMLの例では「user_name: 入力されたもの」「pass: 入力されたもの」のように連想配列のような形でデータを持っています。

 

中身を確認したい場合

単純にconsole.logでは中身を見ることはできません。

以下のようにすれば見ることはできます。

// Safari以外で動くはず
for(var item of formdata){
  // [key, value]という形で入る
  console.log(item);
}

 

何もないところから作成する

var formdata = new FormData();

引数に何も与えなければ、空のFormDataオブジェクトができます。

これにデータを追加する場合は、次のようにします。

 

データを追加する

formdata.append("hoge", "fuga");

これで、キーがhoge、値がfugaのデータが新しく追加されました。

なお、同じキーに対してデータをappendした時、上書きされず別フィールドして追加される。

 

データをサーバへ送信する

XMLHttpRequestを使ってFormDataをサーバへ送るには以下のとおり。

var xhr = new XMLHttpRequest();
xhr.open("POST", "/path/to/hoge.cgi");
// ~~ 設定のあれこれ ~~ 
xhr.send(formdata);

JSONに直したりする面倒なこともなく、sendメソッドの引数にFormDataを渡すだけ。

 

 

基本的には、これまでの方法で利用できます。

その他、最近のブラウザでは使えるメソッドについてもメモしておきます。

 

FormDataの便利なメソッド

以下のメソッドは、最近のブラウザでは実装されているはずです。

IE、Edge、Safariでは実装されていません。(2017/09/10 現在)

※Edgeでは、フラグにより利用できるようです。

以下の画像は、FormData – MDNからの引用です。

 

get()/getAll()

formdata.get("key");
// => value or null

FormDataの中に、引数で渡すキーを持っていればそれを、なければnullが返ってきます。

 

1つのキーに対して、複数の値を持っている場合は、getAllで全て取得できます。

formdata.getAll("key");
// => [value1, value2, ...] or []

キーに対して値を持っていれば、それが入った配列を返し、なければ空の配列を返します。

 

set()

appendと同様、FormDataオブジェクトへ新しい値を追加します。

formdata.set("key", "value");

appendとの違いは、

  • append
    • データの有無に関わらず、引数のkeyとvalueを追加する
  • set
    • keyが既に存在する場合、valueを上書きする
    • keyが存在しない場合、新しく設定する

 

既存のデータを上書きする時は、(使えるのであれば)setで行うべきでしょう。

 

entries()

FormDataオブジェクトが持っているkeyとvalueのペアを繰り返し取得するためのiteratorを返す。

for(var item of formdata.entries()){
  // item[0]: key,  item[1]: value
  console.log(item[0] + " : " + item[1]);
}

なお、このコードは前述の「中身を確認したい場合」にあるものと等価です。

 

 

delete()

FormDataオブジェクトが持っているkey、valueを削除する。

formdata.delete("key");

キーがあれば、それに一致するvalueを削除します。

複数一致する場合、すべてが削除されるようです。

 

 

keys()/values()

entries()のうち、keyのみのiteratorを返すものがkeys()。

valueのみのiteratorを返すものがvalues()です。

 

参考:FormData – MDN

 

さいごに

基本的には、「FormDataの基本」にあるものはIE以外では動くはずです。

「FormDataの便利なメソッド」を使う場合は、IE、Safari、Edge(フラグによる切り替え必要?)を切り捨てるしかありません。

 

しかし、それを捨ててでも使うべきでしょう。

自分でデータを送るためのオブジェクトを作ったり、JSONへの変換など、

サーバへのデータを送るための手順で起こりうるミスを防ぐことができます。

 

入力されたデータをJSでチェックしないのであれば十分使えるものでしょう。

 

 

今回は、ここまで。

おわり

Posted by しきゆら