IE8でのHTTPステータスコード204の扱いについて

サーバー側でJersey、クライアント側でjQuery v1.6.1を使用して、6割仕事4割プライベートなWebアプリを作成中に困った現象が発生したのでメモ。

Ajax通信をしたときの共通エラー処理(ダイアログの表示など)を行うため、クライアントサイドでjQueryのajaxErrorメソッドを使用して下記のようなコードを書きました。

    //Ajax使用時の共通エラー処理
    $(document).ajaxError(
        function(event, XMLHttpRequest, options, thrownError)   {
            //何かしらのエラー処理。
        }
    );

本来であれば、httpステータスコード200番代(「成功」)であればエラー処理は実行されず、それ以外のステータスコード(例えば、404 Not Found)が戻った場合にはエラー処理が行われるはずです。

今回は例として下記のようなURLへアクセスするケースを考えます。

操作の内容: ショッピングサイトで、あるユーザー(${userId})のカートへ商品を追加する
URL: http://hostname/Example/shopping/rest/${userId}/cart
Httpメソッド: POST
リクエストヘッダの'Accept'フィールド内容: application/xml, text/xml, */*;
正常に処理が行われた場合のHttpステータスコード: 204
レスポンスボディ内容: 無し

取り敢えずIE8, Google Chrome, Firefoxで上記URLへアクセスし、処理が正常に行われた場合の動作を比較したところ、下記のようになりました。

  • Google Chrome: 特に問題なし(共通エラー処理は実行されず)
  • Firefox: 特に問題なし(共通エラー処理は実行されず)
  • IE8: レスポンスコード204なのに何故かエラー処理が実行される。

また空気を読まない(ついでにRFCも禄に読んでないっぽい)IEだよ。
ちなみにIE8でのエラーの詳細は下記の通り

XMLHttpRequest.status: 204
XMLHttpRequest.statusText: parsererror

原因は?

過去にも同様の現象が発生していたようです。


Ajax XML response parsing raises error on empty response body in jQuery 1.1.4 -
jQuery Development |
Google Groups

上のやり取りを見ると、開発サイドでは"Content-Typeが'application/xml'の場合には空文字は妥当でないXMLなんだからエラーだろ常考。レスポンス本文に何か妥当なXMLデータを入れるか、Content-typeを'text/plain'に変えろ"的なことを言っていますが、そもそもステータスコードについて定めたRFC2616では、

204 レスポンスは メッセージボディを含んではならないので、常にヘッダフィールドの後の最初の空行で終了する。

[Studying HTTP] HTTP Status Codeより)

とあるのではっきり言って暴論です。ということで、IEのバグ+jQuery内部でIEのバグに対して何も対応をしていないことが本現象の原因かと。

また、過去バージョンのjQueryではIE系ブラウザでも同じ状況でエラーと判定しないようですが、v1.6.1ではエラーとなるようです。

場当たり的解決法

とりあえず、クライアント側でステータスコード204をスルーすることで解決。

    $(document).ajaxError(
        function(event, XMLHttpRequest, options, thrownError)   {
            if(XMLHttpRequest.status != 204){
                //何かしらのエラー処理。
            }
        }
    );

今後を考えると200番台のステータスコードについては全てスルーしたほうが良さげですが・・・。今回は今後の発展性やメンテナンスを考慮しなくていいので、取り敢えずこれで対応終了。