表題の件、原因の詳細が分かる方いらっしゃったら解説をお願いしたいです。
追加の情報の要望や、検証方法についても教えて頂ければ幸いです。
前提
AdobeAirを使ってPasoliを使用し、Fericaのカード情報を読み取って、Ajax通信でそのカード情報をPOSTする仕組みを構築しています。
AdobeAirで読み取った情報をJSへ渡し、そこで読み取った情報の展開と、隠されたボタン$("#read")をクリックさせ、以下処理を発火させています。
ボタンの処理のバインドはここ以外では行っていません。
javascript
1$(function(){ 2 $("#read").click(function ajaxpost(e) { 3 // 多重送信を防ぐため通信完了までボタンをdisableにする 4 var button = $(this); 5 button.attr("disabled", true); 6 set_msg("waiting","読込中") 7 8 var jsondatabody = '"'+'i_media_id'+'":"' + $("#i_media_id").val() + '"'; 9 jsondatabody += ',"'+'todokede_cd'+'":"' + $("#todokede_cd").val() + '"'; 10 11 //送信するJSONデータを作成 12 var data = JSON.parse("{"+jsondatabody +"}"); 13 14 //URLを取得 15 var targeturl = "ReadPage.html"; 16 17 return $.ajax({ 18 type:"POST", // method = "POST" 19 url:targeturl, // POST送信先のURL, 20 data:JSON.stringify(data), // JSONデータ本体 21 contentType: 'application/json; charset=UTF-8', // リクエストの Content-Type 22 cache: false, // キャッシュさせない 23 //dataType: "json", // レスポンスをJSONとしてパースする...(Unicodeに変換しているためコメントアウト) 24 }) 25 26 .done(function(result) { 27 // 成功時処理 28 29 //Jsonにパース 30 var json = JSON.parse(unescape(result)); 31 32 $(json).each(function(){ 33 var wktitle = this.title; 34 var msgbody = this.msgbody 35 var autoClearMs ; 36 37 var audio ; 38 39 audio.load(); 40 audio.play(); 41 42 }) 43 set_msg("ready","カードをかざして下さい。") 44 45 }).fail(function() { 46 // エラー 47 alert("読取中にエラーが発生しました。システム管理者へ連絡してください。"); 48 }).always(function(result) { 49 // 完了処理 50 button.attr("disabled", false); // ボタンを再び enableにする 51 52 }); 53 54 }); 55});
症状
画面にはtodokede_cdを変更するボタンがあり、このボタンを押すとサーバーと同期通信を行い、一度画面がリロードされます。
一度画面をリロードした後で上記処理を実施した場合、前回の読み取りデータ+今回の読み取りデータがPOSTされてしまいます。
発生条件
端末によって発生する場合としない場合があります。(OSはいずれもWindows7、IE11で実施してます)
確率も100%起こる端末、10%くらい、0%とさまざまです。。。
また、$("#read")を表示させて画面からボタンクリックした場合の発生率は0%です。
おなじく、F12で開発者モードを開きながら実行した場合も発生率は0%です。
試したこと
上記のとおりF12で開発者モードを開きながら実行すると発生しないためなかなか検証が出来ていません。
①Alertでのデバック
javascript
1$("#read").click(function ajaxpost(e) {
の下に
javascript
1alert("a");
を入れてみましたが、2回送信が起こる状況では、アラートが出た時点で前回情報のPOSTが飛んできてしまいます。(OKを押すと今回の情報がとんできます)
②bindをオフ
javascript
1 $("#read").click(function ajaxpost(e) {
の前に$("#read")ボタンへのクリックバインドをoffにする処理を入れてみましたが、効果はありませんでした。
③ajaxオブジェクトの有無を確認
javascript
1$("#read").click(function ajaxpost(e) {
の下に
javascript
1if (jqxhr) { 2 return; 3 }
を入れ、Ajax通信のところを
javascript
1return jqxhr= $.ajax({
へ変更したところ、現象は起きなくなりました。
ただ、このjqxhrのif文の中にalertを入れてもalertは起きません。
returnするのをやめた場合2回送信がされてしまうので効果はあると思うのですが…
どういう理論でうまくいってるのかよく分かっていません。
以上です。よろしくお願いいたします。
======================20180302追記
色々といじっていたところ、突然再現していた端末ですら再現率が0%になってしまいました。
発生時とソースを全く同じにしたのですが、全く再現せず…
JSとは関係ないんでしょうかね…もう何もわかりません…
======================20180305追記
html
1<div class="hide"> 2 <button type="button" class="btn btn-default" name="read" id="read" >読みとり(本来は非表示)</button> 3 <button type="button" class="btn btn-default hide" name="read_get_felica_id" id="read_get_felica_id" >カードリーダのオープン(本来は非表示)</button> 4</div>