※めんどくさい && アホの証拠として残しておくため 消しませんが、ここに書いた方法だと200以外の404とかに対応できないです。つまりダメです
http://d.hatena.ne.jp/NeoCat/20110206/1296934235
これって結局、根本的には
- JSONPにおいては、200であっても「JavaScriptとして評価できない文字列が返ってきた場合」「こっち側で指定したコールバック関数(callbackA)の呼び出しがちゃんと行われなかった場合」にはエラー扱いにしたい
- そのためには、script elementでloadされるJavaScript の評価が成功した場合でも失敗した場合でも必ず呼ばれるコールバック関数(callbackB)が必要だ
- 実行順はcallbackA -> callbackBとなる必要がある(でないとJSONPの実行結果がとれない)
という要件があった上で、
- script elementのonloadとonerrorはクロスブラウザ的な意味で信用できない
- なので、iframeをかませてそのonloadをcallbackBとして使おう
- callbackAの呼び出しが正しく行われた否かは、引数をまるっと変数に代入しておいて判定しよう
というロジックに至ったお話だと思うのだが、それだけなら別にiframeかます必要はなくて、callbackBとしてonloadが走るブラウザではonload、IEではonreadystatechangeを使って
var xds = { load: function(url, onsuccess, onerror, callbackKey) { callbackKey = callbackKey || "callback"; var script = document.createElement("script"); script.onload = script.onreadystatechange = function() { if ( this.readyState && this.readyState !== "loaded" ) return; if (xds.result) { if (onsuccess) onsuccess.apply(this, xds.result); } else if (onerror) { onerror(); } script.parentNode.removeChild(script); }; script.src = url + (url.indexOf("?") === -1 ? "?" : "&" ) + callbackKey + "=xds.callback"; document.getElementsByTagName("head")[0].appendChild(script); }, callback: function() { xds.result = arguments; } };
こういうコードでも元々の要件は満たしている気がする。
または、僕が何か見落としているのかもしれない。
- > よく考えたらこれだと200以外の時ダメでした。