JSONPの404は捕捉できない
クロスオリジンでAjax通信をする場合に使うJSONP。
アクセス先のステータスコードが400系や500系などの場合、エラーとして捕捉できず無限に待ち続ける状態になる。
// jQuery使用
$.ajax({
url: '//example.com/api/',
type: 'GET',
dataType: 'jsonp',
})
.done(function(){
// 当然ここは実行されない
})
.fail(function(){
// ここも実行されない!
});
なぜか
JSONPの原理を考えてみれば、当然といえば当然である。
- コールバック関数を定義
- scriptタグにアクセスポイントのURLを埋め込む
- アクセスポイントのリソースは、JavaScriptファイルとして読込・実行され、用意しておいたコールバック関数が実行される
ここで、scriptタグで読み込む先が404とか500であった場合、読み込むべきリソースが無いのであるから、
当然ながら用意されたコールバック関数は実行されない。
response bodyに中身が入っていても、クライアント(ブラウザ)によってそれは無視される。
XHRと違って、JavaScriptはアクセスポイントへのリクエストを取り扱っているわけではない。
JSONPのアクセスでは、JavaScriptは、scriptタグを生成してコールバック関数の実行を指を咥えて待っているだけなのだ。後のリクエストはブラウザが勝手にやっているに過ぎない。
jQueryのドキュメントにも、エラーハンドリングできない旨は書いてある。
https://api.jquery.com/jquery.ajax/
settingsのerrorプロパティ
Note: This handler is not called for cross-domain script and cross-domain JSONP requests.
どうするのか
iframeを使ってアクセスポイントの中身を探る方法もあるようだが、
サーバがそれなりに素早く正常値を返してくれるのが期待できるのであれば、
timeoutを設定することで良いのではないか。
// jQuery使用
$.ajax({
url: '//example.com/api/',
type: 'GET',
dataType: 'jsonp',
timeout: 2000,
})
.done(function(){
// 当然ここは実行されない
})
.fail(function(){
// アクセスできない場合は、2秒後にこれが実行される
// 正常にレスポンスが返ってきても場合でも、2秒以上かかってしまうと実行されてしまうのだが
});
JSONP自体は、本質的にJavaScriptに備わっているわけではない裏技的仕組みなので、エラー時にどうするかの真っ当な仕組みは用意されていないということだ。
timeoutでお茶を濁すような方法を紹介したが、
この辺の処理を厳密にやるべき案件なのであれば、JSONPなど使用せず、
同一オリジンでAPI提供するようにするか、Access-Control-Allow-Origin
ヘッダーを付けるなど、インフラ側・サーバ側にちゃんと対応してもらおう。
何でもかんでもフロントエンドに吸収させようとしないでくれ。
Author And Source
この問題について(JSONPの404は捕捉できない), 我々は、より多くの情報をここで見つけました https://qiita.com/HieroglypH/items/9db6265dea0193a2d327著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .