質問: this.msgbody var autoClearMs ; var audio ; audio.load(); audio.play(); }) set_msg("ready","カードをかざして下さい。") }).fail(function() { // エラー alert("読取中にエラーが発生しました。システム管理者へ連絡してください。"); }).always(function(result) { // 完了処理 button.attr("disabled", false); // ボタンを再び enableにする }); }); }); ``` **症状** 画面にはtodokede_cdを変更するボタンがあり、このボタンを押すとサーバーと同期通信を行い、一度画面がリロードされます。 一度画面をリロードした後で上記処理を実施した場合、前回の読み取りデータ+今回の読み取りデータがPOSTされてしまいます。 **発生条件** 端末によって発生する場合としない場合があります。(OSはいずれもWindows7、IE11で実施してます) 確率も100%起こる端末、10%くらい、0%とさまざまです。。。 また、$("#read")を表示させて画面からボタンクリックした場合の発生率は0%です。 おなじく、F12で開発者モードを開きながら実行した場合も発生率は0%です。 **試したこと** 上記のとおりF12で開発者モードを開きながら実行すると発生しないためなかなか検証が出来ていません。 1Alertでのデバック ``` $("#read").click(function ajaxpost(e) { ``` の下に ``` alert("a"); ``` を入れてみましたが、2回送信が起こる状況では、アラートが出た時点で前回情報のPOSTが飛んできてしまいます。(OKを押すと今回の情報がとんできます) 2bindをオフ ``` $("#read").click(function ajaxpost(e) { ``` の前に$("#read")ボタンへのクリックバインドをoffにする処理を入れてみましたが、効果はありませんでした。 3ajaxオブジェクトの有無を確認 ``` $("#read").click(function ajaxpost(e) { ``` の下に ``` if (jqxhr) { return; } ``` を入れ、Ajax通信のところを ``` return jqxhr= $.ajax({ ``` へ変更したところ、現象は起きなくなりました。 ただ、このjqxhrのif文の中にalertを入れてもalertは起きません。 returnするのをやめた場合2回送信がされてしまうので効果はあると思うのですが... どういう理論でうまくいってるのかよく分かっていません。 以上です。よろしくお願いいたします。 ======================20180302追記 色々といじっていたところ、突然再現していた端末ですら再現率が0%になってしまいました。 発生時とソースを全く同じにしたのですが、全く再現せず... JSとは関係ないんでしょうかね...もう何もわかりません... ======================20180305追記 ``` 読みとり(本来は非表示) カードリーダのオープン(本来は非表示) ```
回答: リロード前とリロード後の両方のデータが送信されるということは、クリックイベントを二重登録ではなく、 何らかの原因でリロード前の項目が存在している可能性が高いですね。 (項目が残っているので、その項目にバインドされたイベントも残っている) なので、原因はリロード処理にある可能性が高いので、リロード処理がわからないとなんとも言えないですね。 また、ajaxの戻り値をjqxhrに代入する処理とjqxhrの判定処理をいれた場合に 何故、二重送信されないのかについては、 クリックイベントの処理が2つ動かされてしまった場合でも、 先にajaxの処理を始めたほうが、jqxhrにjqXHRオブジェクトを代入し、(undefinedではなくなる) 後のほうはif文にてそれを判定して、ajaxを行う前に処理を終了しているだけです。