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
原因は?
過去にも同様の現象が発生していたようです。
上のやり取りを見ると、開発サイドでは"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番台のステータスコードについては全てスルーしたほうが良さげですが・・・。今回は今後の発展性やメンテナンスを考慮しなくていいので、取り敢えずこれで対応終了。