SSブログ

[Note] iPad で $.ajax の失敗 - Failure of $.ajax in iPad [iOS]

jQuery の $.ajax を使っている Web システムで、iPad だと特定の操作で特定のエラーメッセージが出現することが発覚しました。

I found that the Web system which used $.ajax of jQuery output specific error message by specific operation.

メッセージ文字列から追跡したところ、$.ajax を自作の JavaScript オブジェクトで隠ぺいし、エラーハンドラー内で決められた文字列を alert するようハード コーディングされていたため、この隠ぺいされた独自の Ajax が失敗すると、冒頭の特定のエラーメッセージが出ていたことがわかりました。

I traced the problem by the message string, then I found the concealed someone's own making code including $.ajax, and the code had a hardcoded error handler with "alert", so if the $.ajax failed the error handler output above specific error message.

また、ユーザーが値を入力できるほとんどのエレメントでフォーカス アウト系イベントをトラップし、無条件でこの独自の Ajax を実行していました。

And, most editable elements' focus out events were trapped to call the concealed own Ajax process unconditionally.

この時点で、こういう作り自体がナンセンスなんだけど。

I was sure that such a process is nothing but nonsense.

では、なぜ特定の操作で必ず $.ajax がエラーとなるのか。

Then, why did this system fail invariably with $.ajax by specific operation?

追調査した結果、$.ajax のリクエスト処理中にページのアンロードがかかると、xmlHttpRequest が status = 0 で失敗していました。

With more trace, if page unload occurred in the period of the $.ajax, the $.ajax failed with xmlHttpRequest status = 0.

ページのアンロードを誘発する遷移に関する操作が、この現象のトリガーでした。

Operation about the page transition to cause the page unload was the trigger of this problem.

ネットで調べてみたところ、ページのアンロード時に status = 0 になる現象は、特定のブラウザーと jQuery のバージョンの組み合わせで起きるようです(2.0.0 以降では起きないとか???)。

According to articles in the net, the problem that the $.ajax is fail with status = 0 at the time of page unload will be happened by the specific combination of the browser and the jQuery version(this problem fixed with 2.0.0?).

手元の環境では、iOS 6.x および iOS 7.0.x と、jQuery 1.8.2 の組み合わせで問題が起きていました。

In my case, the problem occurred by a combination of jQuery 1.8.2 and iOS 6.x or iOS 7.0.x.

とはいえ、以前記事にした通り、iPad では beforeunload を捕まえられないし、代わりのイベントの pagehide も発生条件が一定でないので、$.ajax を中断するにもキッカケがありません。

But, as I took an article the other day, iPad Safari Mobile doesn't fire beforeunload event, and the outbreak condition of pagehide event is not constant, so there is no opportunity to abort $.ajax.

本件のケースでは納期が迫っていたため、エラーメッセージの出力を抑制するフラグを仕込んで逃げました。

In this case, there was no enough time by the deadline, I evaded this problem by creating the flag which controlled the output of the error message.

ライブラリにはバグがあると思えということと、内部処理とプレゼンテーション処理は分離しろ、ということですね。

A library has a bug, and the processes should be separated in internal and presentation. 


【Note】iPad の pagehide の厄介ごと - awkward "pagehide" in iPad [iOS]

今回は、試しに英語の文章も併記します。間違えていたらごめんなさい、教えてください。

I write contents by English jointly for trial in this time. If I'm wrong, please tell me by comment.

IPad Safari Mobile でページのアンロードを扱う方法については、以前記事にしました。

The other day I wrote an article about how to handle the "page unload" in "iPad Safari Mobile".

ページのアンロードを処理のトリガーにする Web システムを iPad に対応させたい場合は、pagehide イベントしか使えません。

Only "pagehide" event is usable to start some kind of processing in "page unload" in iPad.

しかしこの pagehide、iOS のバージョンによって発生条件が違ったりします。

However, outbreak condition of "pagehide" depends on iOS version.

例えば、複数のタブがあり、タブ A がアクティブでタブ B が非アクティブだとします。

Please imagine, there are 2 tabs, tab A is active and tab B is not.

ユーザーがタブ B を見ようとして、タブ B をタッチした瞬間に…

Then a user touches tab B to watch it, and an active tab is changed; ...

  • iOS 6 ではタブ A の pagehide が発生しません。
  • iOS 7 ではタブ A の pagehide が発生します。
  • "pagehide" of tab A does NOT occur in iOS 6.
  • "pagehide" of tab A occurs in iOS 7.

・・・なんてことに(あれ? 逆だったかな?)。

... awkward(It may be reverse ?)

他のイベントでも、バージョンや環境に依存して挙動が違うものがあるのかもしれませんが。

Similarly, there may be the event that a condition changes under the influence of a version or environment.

ページのアンロード系を処理のトリガーにするのは、やっぱり最初の考え方が間違っているんじゃないかなあ。

I think that it is wrong to start some kind of processing in "page unload".

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。

この広告は180日新規投稿のないブログに表示されます