一回しか押していないのに申し込みが二件届く。二重送信はボタンの作りで防ぐ
反応がないボタンは、もう一度押される。
押せなくするだけでは足りない、二重送信の話。
お問い合わせフォームから、同じ内容の申し込みが二件届くことがある。
名前も本文も一字一句同じで、受け取った時刻だけが数秒違う。
いたずらでも手違いでもないことが多い。
送ってくれた人は、一回しか押していないつもりでいる。
反応がないと、人はもう一度押す
送信ボタンを押してから、実際に受け付けが終わるまでには少し時間がかかる。
内容を保存して、通知のメールを送って、完了の画面を出す。
速い回線でも一秒、混んでいれば数秒。
その数秒のあいだ、画面には何も起きない。
ボタンは押す前とまったく同じ顔をして、そこに座っている。
押した人からすれば、これは「押せていない」のと区別がつかない。
だからもう一度押す。
誰でも、他人のサイトで同じことをしたことがあると思う。
つまり二重送信は、押した人の不注意ではない。
待たせているあいだ、作る側が何も伝えていないせいだ。
JavaScriptができるのは、押せなくすること
いちばん手っ取り早い対策は、押された瞬間にボタンを無効にすることだ。
JavaScript でボタンの disabled を true にすると、それ以降のクリックは効かなくなる。
ただ、ここに初心者がよく踏む段差がある。
送信ボタン自体を無効にするタイミングを間違えると、送信そのものが止まってしまうことがある。
ブラウザは、無効になっている入力欄やボタンの値をサーバーへ送らない。
送信の処理が始まる前に無効にしてしまうと、そのボタンの値が抜け落ちる。
ボタンの値で処理を分けている作りだと、これで動かなくなる。
順番としては、送信の処理を先に走らせて、そのあとで無効にする。
フォームの送信イベントの中で無効化する、と覚えておけばだいたい間違えない。
それでも、JavaScript だけでは守りきれない
ここで終わりにしたいところだけれど、これだけでは足りない。
JavaScript は、見ている人の手元のブラウザで動いている。
何かの理由で読み込まれなければ、無効化のしかけごと存在しないことになる。
開発者向けの画面から、無効を解除して押すこともできる。
もっと素朴な経路もある。
送信は届いていたのに、返事が返る前に回線が切れた。
画面には何も出ないから、押した人は最初からやり直す。
このとき、ボタンの無効化はまったく仕事をしていない。
だから受け取る側でも守る。
フォームを表示するときに、その一回ぶんだけ有効な合言葉を紛れ込ませておく。
受け取ったらその合言葉を使い済みにして、同じものが二度目に来たら受け付けない。
もっと簡単に済ませるなら、同じ相手から同じ内容が短い時間のうちに来たら一件として扱う、という線引きでもいい。
完璧ではないけれど、よくある二重送信はこれでかなり防げる。
いちばん効くのは、押したことが見えるようにすること
しかけを二つ入れたうえで、いちばん効くのは表示のほうだと思う。
押された瞬間に、ボタンの文字を「送信中」に変える。
色を薄くして、指のかたちのカーソルもやめる。
これだけで、二度押しはずいぶん起きにくくなる。
技術で止めるのは、起きてしまったことへの後始末だと思う。
起きなくするのは、待っている人に「いま動いています」と伝えることだ。
ボタンを直すというより、黙っているのをやめる、という話だと思う。
ほかにも書いています
受託・note・スタンプこういう仕組みを作る相談を受けています
毎日の更新・データ集め・集計の自動化/3万円〜収益がいくらだったか、どの施策が外れたか
note / 個人の視点で掘り下げていますスタンプラリーに挑戦する
行った場所は、現地チェックインで記録に残せます※受託の相談とnoteは、運営者が個人で受けている・書いているものです。
