jQueryのajaxが成功しているのにfailで処理される現象の原因と対応方法を解説

jQueryのajaxが成功しているのにfailで処理される現象の原因と対応方法を解説
                 
最終更新日から90日以上経過しています。

以前ちょろっとJavaScript(jQuery)を書いた際にajaxを使用したのですが、

題名の通り、正常にレスポンスが取得できているのにも関わらず、

失敗(fail)として処理されてしまう現象に出くわしました。

 

その時は軽く調べて暫定的に対応してしまったので、しっかり調べてみました。

備忘の為に記事に残し、同じ現象に悩んでいる人の助けになれば。

現象を確認

$.ajax()を利用する場合、下記のような記述になるかと思います。
今回は例としてRedmineのチケット更新APIを実行します。

$.ajax({
    type: 'PUT',
    url: '/issues/999.json',
    headers: {
        'API-Key': API_KEY
    },
    dataType: 'json',
    data: params
    contentType: 'application/json',
}).done(function(resp) {
    console.log(resp);
}).fail(function(jqXHR, textStatus, errorThrown){
    console.log(jqXHR);
    console.log(textStatus);
    console.log(errorThrown);
});

で、PUT処理がステータスコード=200(成功)で終了すれば、done()に処理が流れるはず

が、fail()に入ってきてしまうと。

原因

原因は、下記の通り。

jQuery側でレスポンスの内容をJSON形式にパースしようとして、エラーとなっている。

下のキャプチャを見るとわかるかと思います。(”parsererror”としてfail()に入ってきている。)

以下、こちらのjQuery解説サイトから引用させて頂くと、dataType:”json”を指定した場合、

JSONとしてレスポンスを評価し、JavaScriptオブジェクトが返されます。 このJSONデータは厳格な作法によってパースされるため、奇形と判断されたJSONは拒絶され、パースエラーがスローされます。jQuery1.9からは、空のレスポンスも拒絶されるようになったため、 サーバーは代わりにnullまたは{}を返す必要があります。

との事。

私のRedmineではjQuery1.11.1が適用されておりますので、
空のレスポンスが拒絶されてパースエラーとなっていた、という事のようです。

対応

dataTypeを指定しない ⇒ エラーになる

いくつか同事象について説明しているサイトをみると、

dataTypeを指定しなければjQueryが自動で型を判定してくれる。

との記載を見つけました。
これは、再び前述のjQuery解説サイトから引用させて頂きますが、

あなたが期待するサーバーから返されるデータの型を指定します。 もし指定されなければ、jQueryはレスポンスのMIME typeを元に推察することを試みます。

によるものと思われます。

が、今回のケースでは解決できませんでした
これは下記キャプチャの通り、Redmine側のレスポンスヘッダのContent-Typeが
JSON指定されているから。

自動判定によりJSONと判断され、パースしようとしてパースエラーになってしまう
という事のようです。


dataTypeにtextを指定 ⇒ 解決

上記から、パースされなければエラーにならないと考えられる為、
プレーンテキストとして処理されるよう、textを指定すれば解決しました

成功ロジックのdone()に入ってきました。
Redmineのチケット更新APIの成功レスポンスは、nullでも{}でもなく、””(空文字列)という事がわかります。

おわりに

なにかモヤモヤしていたので、原因がハッキリして良かった。

プログラマがレベルアップする方法って、こういう躓きを解決する積み重ねなんだろうなと。。。

JavaScript(TypeScript)カテゴリの最新記事