質問: jQueryのajaxでクロスドメイン通信した時に、レスポンスのHTTPステータスコードを参照し、 その後の処理を分けたいのですが、期待しているHTTPステータスコードが取得できません。 例えば、あえて401(Unauthorized)を返すような通信を行い、 GoogleChromeの開発者ツールのNetworkタブで見ますと401(Unauthorized)が返ってきていますが、これをJavaScriptのコード上で参照しますと、404(NotFound)が格納されています。 jQueryのajaxではレスポンスのHTTPステータスコードは変換されているのでしょうか? このような場合でJavaScriptのコード上で401を取得する方法はありますでしょうか? クライアントサイド:JavaScrip + jQuery2.0.3 サーバサイド:Apach2.2.3 + Tomcat6 + Java7 クロスドメイン対策はしており、通常時は通信は成功しています。 クライアント側、サーバ側共に、設定などの変更は可能な環境です。 以下、クライアント側の呼出し部のコードです。 ``` $.ajax({ url: "http:xxxxx.com", async: true, type: inType, cache: false, contentType: contentType, data: data, timeout: 60000, xhrFields: { withCredentials: true, }, statusCode: { 401: function() { console.log("call 401"); }, 403: function() { console.log("call 403"); }, 404: function() { console.log("call 404"); }, 200: function() { console.log("call 200"); } }, }).done( function (inRecv, inStatus, inXhr) { console.log("done: inStatus=" + inStatus + " readyState=" + inXhr.readyState + " status=" + inXhr.status + "(" + inXhr.statusText + ")"); return 0; }).fail( function (inXhr, inStatus, inError) { console.log("fail: inStatus=" + inStatus + " readyState=" + inXhr.readyState + " status=" + inXhr.status + "(" + inError + ")"); return 0; }).always( function (inArg1, inStatus, inArg2) { console.log("alwaysFail: inStatus=" + inStatus + " readyState=" + inArg1.readyState + " status=" + inArg1.status + "(" + inArg2 + ")"); console.log("alwaysDone: inStatus=" + inStatus + " readyState=" + inArg2.readyState + " status=" + inArg2.status + "(" + inArg2.statusText + ")"); return 0; }); ``` 画像はGoogleChromeの開発者ツールのスクリーンショットです。 401のハズが、コンソール出力を見ますと404で格納されています。 ![401なのに](https://teratail-v2.storage.googleapis.com/uploads/contributed_images/0b124b2b903c25d6ade2b0902447220a.png) ![404が返る](https://teratail-v2.storage.googleapis.com/uploads/contributed_images/213e91527a6b869c25c84b9e195a2133.png)
回答: 当方の環境で Chrome と Firefox で試しましたが、`jqxhr`も401を返しました。 Chrome のエラーメッセージを拝見しましたが、 No 'Access-Control-Allow-Origin' header とあり、 Same-Origin Policy 違反により、サーバまでリクエストが行ってないのではないかと思いました。 そこで試しに Same-Origin Policy 違反になる teratail にリクエストを飛ばしてみたところ、`jqxhr`は404を返しました。 おそらくローカル環境からWEBサーバにリクエストをしているのが原因なのでは。 ##### 追記 コメントに返信。 > > ただ、サーバ側にてApacheのaccess.logを監視していますと、401でログ出力されており、リクエストはサーバ側へ届いているようです。サーバ側は確かに401を返しているのですが、どこで404に変換されているのか...。 > > > CORSの仕様によりますと、 > > The getResponseHeader() method of XMLHttpRequest will therefore **not expose any header** not indicated above. > > Cross-Origin Resource Sharing > > > とあります。おそらくセキュリティ上の理由からだと思いますが、Same-Origin Policy 違反の場合、クライアントはレスポンスヘッダをフィルタすることが仕様のようです。ステータスコードについてはそのような明示的な記述はありませんが、同様に処理されるのが妥当のように思えます。