Sep 06, 2006

OperaでJSONPを非同期リクエストする

JSONP が Opera だと非同期処理できない
http://d.hatena.ne.jp/secondlife/20060906/1157515075

に書かれているとおりOperaだとscript要素を足した瞬間にJavaScriptの実行が止まって、ロード完了まで後続のスクリプトが実行されなくなります。

サンプル
http://la.ma.la/misc/js/opera_jsonp_test.html

そこで、リクエストの度にダミーのIFRAMEを作って、そのIFRAME内のcontentWindowで実行するという方法を試してみました。
IFRAME内でJSONをロードするサンプル
http://la.ma.la/misc/js/iframe_jsonp_request.html

なんかIEで動かないっぽいけど気にしない。相変わらずタイマーは停止しますが、appendChildした後のscriptも実行されます。ただIFRAMEを生成する分遅くなっていまいちな感じです。で、一見並列でリクエストされているように見えるのですが、コネクションを見張ってみたら、最初のscriptがロード完了するまで次のscriptを読まない、リクエストすらしていないようでした。

そして色々考えた結果、script要素を追加するタイミングをsetTimeoutでずらしてやればいいんじゃないかと言うことでやってみたのがこれ。
http://la.ma.la/misc/js/jsonp_request_with_delay.html

ディレイなしだとスクリプト追加直後に書いたコードが、外部スクリプトのロード後に実行されてうまく動かないけれど、ディレイを入れるとうまく動く。他のブラウザではどちらでも問題は無し。

非同期と言えるかどうかは微妙だけど、読み込み完了まで何も実行されない、という状況はある程度回避できそう。

まとめると
- Operaではタイマーが止まるのでタイムアウトを処理するのはなんか無理っぽい
- IFRAME使ってもscriptは順次読み込まれて、並列にリクエストされることはない
- script挿入のタイミングをずらしてやればコネクション数の管理なんかはできる

これぐらいか。

IFRAMEの中で処理する方法は、IFRAME内で実行されて名前空間が分かれるのでコールバック関数名を共通にできる(ユニークなIDをつけなくてもいいので、ブラウザのキャッシュが効きやすい)っていうメリットがあるんだけど、その他もろもろのデメリットを考えると大したメリットでもないかなーという具合。
Posted at 15:14 | WriteBacks (6) | Edit
Edit this entry...

wikieditish message: Ready to edit this entry.
















A quick preview will be rendered here when you click "Preview" button.