japan.internet.com The Internet & IT Network


RSSニュース検索
カテゴリ
> トップページ
> Webビジネス
> Eコマース
> Webファイナンス
> Webマーケティング
> パブリック
> Webテクノロジー
> 携帯・ワイヤレス
> Linux Today
> Linux Tutorial
> J.I.C.ブログ
キャリア
> 転職ならen
> 派遣ならen
> アルバイトならen
> IT求人情報
ヘッドライン
> 今日のヘッドライン
> 週間ヘッドライン
Special Link
> フォトコミュニティ
> ストックフォト
> クリップアート
> イラスト
> フェリカ
> Web2.0
> 写真
イベント&セミナー
> イベントカレンダー
> 書評「IT の耳」
> 出張・接待検索
> ニュースガジェット 注目
無料ニュースメール
> 新規登録
> 変更・解除
> オプトインメールの登録・変更・解除
インフォメーション
> パートナーサイト
転職ならエン
就職ならen
求人ならen
履歴書ならen
アルバイトならエン
CRM/SFAならオラクル
> グループ会社
株式会社アエリア
(株)サンゼロミニッツ
株式会社エアネット
> お問い合わせ
> 広告掲載について
> リンクについて
> 著作権について
> その他お問い合わせ
> 利用規約
> 個人情報保護方針
> 会社概要地図
デベロッパー 2007年1月16日 10:00
デベロッパー・バックナンバー
JavaScriptを利用してフォームの二重送信を防止する

著者: Scott Mitchell  オリジナル版を読む プリンター用 記事を転送
2007年1月16日 10:00 付の記事
海外internet.com発の記事
このエントリーを含むはてなブックマーク この記事をクリップ! Buzzurlにブックマーク Yahoo!ブックマークに登録 newsing it!

はじめに

 ユーザーがフォームの送信ボタンをクリックすると、ブラウザは指定されたURLのWebサーバーに要求を送ります。すると、Webサーバー側でユーザーの入力が処理され、入力に基づいて何らかのアクションが実行されます。例えばデータベースレコードが追加されたり、電子メールが送信されたりします。問題は、ユーザーがフォームを送信しても、サーバーからの応答がなかなか返らない場合です。ユーザーはクリックが「効かなかった」と考えて、何度も送信ボタンを押してしまうことがあります。その結果、フォームが二重に送信されて、2つのデータベースレコードが追加されたり、2通の電子メールが送信されたりする可能性があります。

 先日、ASP101.comに掲載されているある豆知識が目にとまりました。「Stop Users from Double Clicking(ユーザーによる二重クリックを防止する)」と題するその豆知識では、フォームの送信ボタンにちょっとしたJavaScriptを追加し、ユーザーがフォームを2回以上送信できないようにする方法が紹介されていました。この方法は、ボタンのクライアント側onclickイベントで、ボタンのdisabledプロパティをtrueに設定するという実に単純なものです。

 私のプロジェクトでは、いつももう少し複雑な別の方法を使っています。単に送信ボタンを無効にするのではなく、画面を「フリーズ」させて、データが処理中であることを示すメッセージを表示するという方法です。個人的には、フリーズした画面のルックアンドフィールの方が気に入っています。この方が、データがサーバーに送信されて処理中であることがよく分かるからです。さらに、ユーザーがページ上の他の送信ボタンをクリックするのを防ぐこともできます。本稿では、この2種類の方法について説明します。

クリックされたボタンを無効にする

 多くのWebサイトでは、クリックされた時点で送信ボタンを無効にすることによって、ユーザーがフォームを二重に送信できないようにしています。通常は送信ボタンを無効にすると共に、ボタンのラベルを初期値(「送信」など)から別の値(「送信済み」など)に変更して、アクションが実行されたことを示します。ラベルを変更してボタンを無効にするには、ボタンのクライアント側onclickイベントハンドラで次のようなJavaScriptを使います。

<script>
   function DisableButton(b)
   {
      b.disabled = true;
      b.value = ’Submitting’;
      b.form.submit();
   }
</script>

<p>
   Click the button to see how it can be disabled and
   have its text changed when clicked...
</p>

<p>
   <input type="submit" name="SubmitButton" id="SubmitButton"
          value="Submit"
          onclick="DisableButton(this);" />
</p>

 このonclickイベントハンドラでは、DisableButton(button)関数を呼び出し、ボタンへの参照(this)を渡しています。DisableButton(button)では、ボタンのdisabledプロパティをtrueに設定し、value(ボタンに表示されるラベル)を「Submitting」に設定します。この動作をデモで実際に確認してみてください。

無効になったボタンと、フォームの送信時に送信されるデータ
 警告:ブラウザはフォームの送信時に、無効に設定されているコントロールのデータを送信しません。この例の送信ボタンは、クリックされた時点でJavaScriptによって無効に設定されるため、ブラウザは送信ボタンがクリックされたという情報をフォームの送信に含めません。このため、ASP.NETを使用している場合は、対応するButton WebコントロールのClickイベントが起動しなくなります。送信ボタンのクリックによってポストバックが発生したということがASP.NETエンジンに通知されないからです。これが問題になる場合は、次のどちらかの方法を使用します。
  • この後で説明する、画面を「フリーズ」させる方法を使います。
  • DisableButton(button)のJavaScriptに手を加え、ボタンを無効にする代わりに、ユーザーがフォームを二重に送信できないようにします。例えば、無効状態を表すダミーのボタンを用意し、初期設定で非表示にしておくという方法が考えられます。本物の送信ボタンがクリックされたら、CSSルールで送信ボタンを非表示にし、このダミーのボタンを表示します。

フォームの送信時にページを「フリーズ」させる

 商用のWebアプリケーション(FogBugzなど)には、フォームの送信時に画面を「フリーズ」させて、フォームの二重送信を防いでいるものがあります。具体的には、ページ上の他のすべての要素の前面に、絶対位置で指定された要素(通常は<div>要素)をフルスクリーンで配置することによって画面をフリーズさせています。これにより、要素の背後にあるコンテンツ全体が覆われて、ユーザーはフォームの要素を操作できなくなります。

 最初に、フリーズした画面の外観を指定するいくつかのカスケードスタイルシート(CSS)クラスを定義します。次の3つのCSSクラスを使います。

  • FreezePaneOff
  • <div>要素を「非表示」にして、ページを操作できるように(つまりフリーズしていない状態に)します。
  • FreezePaneOn
  • フリーズした画面を表す要素は、実際にはフルスクリーンの<div>要素であり、その中にメッセージ(「要求を処理しています」など)を表示する<div>要素が含まれています。このCSSクラスは、外側の<div>の設定を定義します。
  • InnerFreezePane
  • 内側の<div>要素のスタイル設定を指定します。この要素は、ユーザーにメッセージ(「要求を処理しています」など)を表示します。

 さらに、内側と外側の<div>要素を定義し、これらの要素を操作して画面をフリーズさせるJavaScript関数を作成する必要があります。この関数では、これらの<div>要素のclass属性を、デフォルトのCSSクラス(FreezePaneOff)から、フリーズしたフレームを表すCSSクラス(FreezePaneOnInnerFreezePane)へと変更します。

 まずCSSクラスから始めましょう。

<style type="text/css">
   .FreezePaneOff
   {
      visibility: hidden;
      display: none;
      position: absolute;
      top: -100px;
      left: -100px;
   }

   .FreezePaneOn
   {
      position: absolute;
      top: 0px;
      left: 0px;
      visibility: visible;
      display: block;
      width: 100%;
      height: 100%;
      background-color: #666;
      z-index: 999;
      filter:alpha(opacity=85);
      -moz-opacity:0.85;
      padding-top: 20%;
   }

   .InnerFreezePane
   {
      text-align: center;
      width: 66%;
      background-color: #171;
      color: White;
      font-size: large;
      border: dashed 2px #111;
      padding: 9px;
   }
</style>

 FreezePaneOffCSSクラスは、非表示の要素(visibility: hidden; display: none;)を定義します。一方、FreezePaneOnCSSクラスは要素を表示状態にし、それをページの上部に配置して幅と高さを最大に設定します。z-index値は、ページ上の要素の「レイヤ」を指定します。ここでは要素がページ上の他の要素の前面に表示されるように、値を999に設定しています。filter:alpha(opacity=85)-moz-opacity:0.85は、それぞれInternet ExplorerとMozilla FireFoxで背景のペインを半透明にします。最後に、InnerFreezePaneCSSクラスで内側のメッセージのスタイル設定を定義します。

 CSSクラスに加えて、ページに<div>要素を追加する必要があります。初期状態では、外側の<div>class属性はFreezePaneOffに設定されています。フォームが送信されると、この属性がJavaScriptによってFreezePaneOnに変更されます。

<div align="center" id="FreezePane" class="FreezePaneOff">
   <div id="InnerFreezePane" class="InnerFreezePane"> </div>
</div>

 次に、ブラウザをウィンドウの上部にスクロールさせ(<div>はページの上部に配置されるため)、外側の<div>のCSSクラスを更新するJavaScript関数を定義します。フォームが送信されるときに、例えば送信ボタンのonclickイベントでこのJavaScript関数を起動する必要があります。

<script language="JavaScript">
   function FreezeScreen(msg) {
      scroll(0,0);
      var outerPane = document.getElementById(’FreezePane’);
      var innerPane = document.getElementById(’InnerFreezePane’);
      if (outerPane) outerPane.className = ’FreezePaneOn’;
      if (innerPane) innerPane.innerHTML = msg;
   }
</script>

<p>
   <input type="submit" name="SubmitButton" id="SubmitButton"
          value="Submit"
          onclick="FreezeScreen(’Your Data is Being Processed...’);" />
</p>

 FreezeScreen(msg)関数は、内側の<div>に表示されるメッセージを入力として受け取ります。このスクリプトの動作をデモで実際に確認してみてください。

 画面をフリーズさせるこの方法には、いくつかの欠点や積み残しがあります。例えば、画面は実際にはフリーズしていません。ユーザーは画面をスクロールしたり、外側の<div>で覆われていない部分のHTML要素をクリックしたり、[戻る]ボタンを押したり、ページを更新したり、さまざまな操作を実行できてしまいます。

 また、この方法は多種多様なブラウザで十分にテストされているわけではありません。IE 6、FireFox 1.5、およびOpera 9.0(半透明の設定を除く)では機能しますが、古いブラウザに対応しているかどうかは分かりません。

 このようにいくつか欠点はあるものの、私のプロジェクトではこの方法がうまく機能しており、読者にもある程度役に立つことと思います。

 では、ハッピープログラミング!

著者紹介

Scott Mitchell(Scott Mitchell)


関連記事
  • Webページ上に状況依存ヘルプを作成する
  • Adobe、『ActionScript』エンジンのソースコードを Mozilla に寄贈
  • Google Web Toolkit:現実的な開発に即したAJAX
  • 『Firefox』、最新版で『JavaScript』関連の脆弱性を修正
  • DisplayTagとJavaScriptによる高機能なテーブルの作成


  • 関連テーマ
  • Opera
  • Mozilla
  • ブラウザ


  • ★最新トップニュース
    コラム IT を変えつつあるのはどの技術?(Webビジネス 8月29日 13:30)
    IT マネジャーと企業幹部の間で、IT を最も大胆に変えつつある技術トレンドを巡って意見の相違があるのは当然だ。これら両陣営は敵対関係にある場合が多いため、両者が今日の技術トレンドを違った角度から見ているのは予想できる。
    国内 CTC、日本 HP、マイクロソフト、Hyper-V ベースの仮想化ソリューションを今秋提供へ(Webテクノロジー 8月29日 13:30)
    伊藤忠テクノソリューションズ(CTC)、日本ヒューレット・パッカード(日本 HP)、マイクロソフトの3社は、2008年8月27日、日本 HP とマイクロソフトのサーバー製品・仮想化技術などを組み合わせ、ソリューション検証を共同で実施する、と発表した。
    海外 Facebook 誕生のいきさつが映画に(Webマーケティング 8月29日 13:20)
    ハリウッドの著名脚本家 Aaron Sorkin 氏が、Facebook に自分のページを開設した。Sony Pictures から依頼を受け、Facebook 誕生物語の映画脚本を書くためという。
    海外 価格競争の影響が出た第2四半期のサーバー売上(Webビジネス 8月29日 13:10)
    IDC が、2008年第2四半期のサーバー市場調査を発表した。売上を得るためにベンダー各社が大幅に値下げしている状況がうかがえる内容だ。
    国内 レッドハット、コンサルもパッケージした低価格の SOA 導入支援サービスを開始(LinuxToday 8月29日 13:10)
    SOA 導入初期段階に必要なコンサルテーションサービスと、ユーザーの状況に合わせて独自に設計する技術者向けのトレーニングをセットにしたもの。JBoss Enterprise SOA Platform ユーザーを対象にしたもの。
    トピックス
    > オススメのIT系求人情報【毎週月曜日更新】
    footer_301.gif


    リサーチ
    > デイリーリサーチDLサイト
    > OnlineResearchPortal (リサーチデータバンク)
    > モバイルリサーチ with goo
    footer_301.gif
    キーワード
    > iPhone > Youtube
    > Google > モバイルノート
    > 半導体 > ウィルコム
    > テーマ一覧はこちら
    footer_301.gif
    セミナー情報
    > 第2回インターネットコムマーケティングセミナー
    「モバイルマーケティングの世界」〜これだけはやっておきたいモバイルマーケティング施策とは〜
    9月24日(水)13:00〜17:00 ITS 山王健保会館
    ※詳しくはこちら
    footer_301.gif
    デベロッパー
    > DevX
    > CodeGuru
    > developer.com
    footer_301.gif
    j.i.c.ブログ
    ブログ一覧
    ベンチャー専門家の目利きブログ「なぜこの企業は伸びるのか?」 【ベンチャー専門家の目利きブログ「なぜこの企業は伸びるのか?」】
    「選択と集中」選択をして集中しない限りは勝てない/メディカル・コミュニケーションズ株式会社(8月29日)
    データメーション 【データメーション】
    Apple は顧客の忠誠心にあぐらをかいているのか? (8月27日)
    Graphic Design Forum 【Graphic Design Forum】
    次へとつながる輪 (8月27日)
    最新テクノロジーの意外な処方箋 【最新テクノロジーの意外な処方箋】
    あなたが舌なめずりしたくなるようなもの(8月26日)
    エンジニアの独り言 【エンジニアの独り言】
    データをローカルに保存するWebアプリケーション(8月22日)
    デスマーチからの脱却 【デスマーチからの脱却】
    30min. iPhoneアプリリリース(8月18日)
    footer_301.gif
    最新コラム一覧
    IT マネジメント IT マネジメント

    IT を変えつつあるのはどの技術?(8月29日)
    最新ハイテク講座 最新ハイテク講座

    繁栄か滅亡か!巨大なエネルギー「原子力」の未来(8月29日)
    developer.com developer.com

    レガシーWebアプリケーションをWebLogic Portal内のフルページIFrameとして統合する(8月29日)
    百式のネットビジネス研究 百式のネットビジネス研究

    友達にあなた特製のクスリを贈ることができる「Get Your Drug On」(8月29日)
    週刊-サイト別アクセス状況データ 週刊-サイト別アクセス状況データ

    ビデオリサーチインタラクティブ調査(月間インターネットオーディエンスデータ)(8月28日)
    「IT の耳」 「IT の耳」

    【書評】『1回の会議・打ち合わせで必ず結論を出す技術』――無意味な会議を撲滅する(8月28日)
    ハードウェアから見たデータベース ハードウェアから見たデータベース

    巨大テーブル活用術1(8月28日)
    ウチのサイトを SEO ウチのサイトを SEO

    検索エンジンが見ている世界(8月27日)
    エンジニア転職ノウハウ開発室 エンジニア転職ノウハウ開発室

    目指せecoエンジニア!グリーンITで地球を救え(8月26日)
    アイレップの SEM フロンティア アイレップの SEM フロンティア

    円滑に SEO を導入・実施するための組織体制を構築しよう(3)(8月26日)
    footer_301.gif
    専門チャンネル
    > セキュリティチャネル > テレコムチャネル
    > サーチエンジンウォッチ
    footer_301.gif
    海外のインターネットコム アメリカ韓国ドイツトルコ
    関連企業のサイト:ストックフォト イラスト ネットストリート ホテル予約サイト タウン情報 出張 事業継承 シミュレーション トランクルーム 優待映画チケット 田舎暮らしガイド オリジナルデザインTシャツ ニタコエ
    Copyright 2008 Jupitermedia Corporation All Rights Reserved. http://www.internet.com/
    space.gif space.gif