Ajax通信を行う時、連続で呼び出されると困る場面ってあります。
▼ 例えばこういうケース
- ボタン押下時にAjax通信するとか、
- Ajax終了後に画像更新したいとか、
そういうときは、あるテクニックを使えば簡単に中止可能です。
ということで記憶の整理も兼ね、
Ajax通信を途中で中止させる方法&コード例をまとめてみました。
Ajax通信を途中でやめるには jqXHR が必要
まず Ajax 通信するときの基本的な手順について
必要なのが jqXHR という Ajax実行時 に返されるオブジェクト
普段 Ajax を使ってると意識しないけど、Ajaxは jqXHR を毎回返してるんです。
▼ 公式リファレンスでの jqXHR の解説(引用)
The jqXHR Object
The jQuery XMLHttpRequest (jqXHR) object returned by $.ajax() as of jQuery 1.5 is a superset of the browser's native XMLHttpRequest object. For example, it contains responseText and responseXML properties, as well as a getResponseHeader() method. When the transport mechanism is something other than XMLHttpRequest (for example, a script tag for a JSONP request) the jqXHR object simulates native XHR functionality where possible.
引用元 : https://api.jquery.com/jquery.ajax/
▼ このリファレンスの超適当な意訳
jqXHRオブジェクトって何?
jQuery1.5 から $.ajax() メソッドで返されるXMLHTTPequest ( jqXHR ) オブジェクトはブラウザ固有の XMLHTTPRequest オブジェクトの上位互換。たとえば、getResponseHeader() メソッド同様、responseText とか responseXML プロパティを持ってる。通信メカニズムが XMLHttpRequest 以外のもの(たとえば、JSONPリクエストのスクリプトタグとか...)の場合、jqXHR オブジェクトはできるだけネイティブなXHR機能をシミュレートするよ
つまり XMLHTTPRequest をjQuery側で使いやすくした上位互換って所ですね。
それで大事なのはここから
この jqXHR にはAjax通信を途中でやめるメソッドが用意されてます。
それが jqXHR オブジェクトの abort メソッドを呼び出すこと
1.止め方としてはまず ajax 呼び出し時に返される jqXHR オブジェクトを保存
1 2 3 4 5 6 |
jqxhr = $.ajax({ url: '/path/to/hoge.php', type: 'GET' }).done(function(resp){ /// レスポンスを受け取る... }); |
2.そして任意のタイミングで abort メソッドを実行するだけ
1 2 3 4 |
/// Ajax通信をやめる if(jqxhr){ jqxhr.abort(); } |
もちろん複数のAjaxを呼び出してるなら、
配列に
jqXHR を格納して、あとでまとめて中止なんてこともできます。
コード例 : ボタン連打で Ajax 連続実行を防止する
Ajaxを呼び出すのはボタンを押したときとかが多いです。
なのでコード例として、ボタン押下時に中止するコード例 で考えてみます。
例えば次みたいなボタン要素を用意
1 2 3 |
<button id="callAjaxBtn"> Ajax通信スタート </button> |
もし Ajax 中止が必要ないなら、次のコードでも十分
1 2 3 4 5 6 7 8 |
$('#callAjaxBtn').on('click', function(){ $.ajax({ url: '/path/to/hoge.php', type: 'GET' }).done(function(resp){ console.log('レスポンス結果 : ', resp); }); }); |
このコードの何が問題かって?
さっきも書いたように、ボタン連打されたら何回でもAjax通信が発生することです。
もちろんボタン要素を無効化する方法もあるですが・・・
変なことをする人のためにも、AJax側にも予防しておいた方がいいですね。
つまり、このコードを次みたいに書き変えればOK
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/// 一時的なjqXHRオブジェくト var jqxhr = null; $('#callAjaxBtn').on('click', function(){ if(jqxhr){ jqxhr.abort(); } jqxhr = $.ajax({ url: '/path/to/hoge.php', type: 'GET' }).done(function(resp){ console.log('レスポンス結果 : ', resp); }); }); |
これで2度押しされたとしても、無駄な通信が発生しなくてすみました。
めでたしめでたし
ここまでのまとめ
以上、Ajax通信を途中で中止する方法でした。
単純に 1.Ajax 呼び出し時に jqXHR オブジェクトを保存 ⇒ 2.任意のタイミングで abort メソッドを呼び出す ・・・みたいな感じなので超簡単。
方法さえ知ってれば簡単です。ではまた($・・)/~~~バイバイ