36561
# 前提

  * XMLHTTPRequestで別ドメイン（Bサイトという）にアクセスする処理
  * Bサイトは、認証機能がありRequest Headerにトークンを渡す必要がある
  * 認証された場合、http status code 200とレスポンスが返ってくる
  * 認証されなかった場合、http status code 401が返ってくる

# 質問

BサイトへXMLHTTPRequestでアクセスし、認証されなかった場合、  
Javascriptでhttp statusを取得すると status code は 0 になっています。  
なぜ、0が返ってくるのでしょうか。  
chrome 開発者ツールのnetworkは、401を返しています。

<https://teratail.com/questions/21794>  
で同様の質問がありましたが、解決されていないため、質問させていただきます。

## プレフライトリクエスト

[![画像の説明をここに入力](https://i.stack.imgur.com/rWlRo.png)](https://i.stack.imgur.com/rWlRo.png)

## 実際のリクエスト (status 401が返ってきている)

[![画像の説明をここに入力](https://i.stack.imgur.com/E2ECV.png)](https://i.stack.imgur.com/E2ECV.png)

## Javascript （status 0になっている）

[![画像の説明をここに入力](https://i.stack.imgur.com/TPxPg.png)](https://i.stack.imgur.com/TPxPg.png)
CC BY-SA 3.0
2017-07-14T07:03:29.103
36352
2017-07-21T07:50:18.333
2017-07-14T07:41:43.767
22993
22993
question
javascript
クロスドメイン通信でhttp status code が0
ブラウザの仕様かもしれません。  
[MDNのリファレンス](https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest/status)で以下のように記載されています。

> Before the request is complete, the value of status will be 0. It is worth
> noting that browsers report a status of 0 in case of XMLHttpRequest errors
> too.
```

    リクエストが完了する前はstatusは0である。XMLHttpRequestのエラーもまたブラウザは0をレポートする。
    
```
CC BY-SA 3.0
2017-07-14T09:44:15.443
36357
2017-07-14T09:44:15.443
20272
36352
answer
[RFC7235 3.1. 401 Unauthorized](https://www.rfc-
editor.org/rfc/rfc7235#section-3.1)から引用します。

> The 401 (Unauthorized) status code indicates that the request has not been
> applied because it lacks valid authentication credentials for the target
> resource. **The server generating a 401 response MUST send a WWW-
> Authenticate header field** (Section 4.1) containing at least one challenge
> applicable to the target resource.

と401レスポンスには`WWW-Authenticate`ヘッダーが必須です。しかし画像を見る限り`WWW-
Authenticate`が含まれていません。このためブラウザーは認証処理をできずに困ったためエラーと見なしたのだと思います。

エラー時に`XMLHttpRequest.status`が`0`を返すのはmaotさんの回答の通りです。
CC BY-SA 3.0
2017-07-14T13:33:01.290
36364
2017-07-14T13:33:01.290
2021-10-07T07:34:52.683
-1
4236
36352
answer
XMLHttpRequest Standard では "netword error" なるものが定められています。

>   1. If the send() flag is unset, return.
>   2. If response is a [network
> error](https://fetch.spec.whatwg.org/#concept-network-error), run the
> request error steps for event error and exception NetworkError.
>

>
> (引用元: [4.5.6. The send() method - XMLHttpRequest
> Standard](https://xhr.spec.whatwg.org/#handle-errors))  
>  (引用元-日本語訳: [4.5.6. send() メソッド - XMLHttpRequest Standard
> （日本語訳）](https://triple-underscore.github.io/XHR-ja.html#handle-errors))

リンク先の Fetch Standard を参照すると、"netword error" の際には `status` に 0 が代入されるとあります。

> A response whose type is "error" is known as a **network error**.  
>  A network error is a response whose status is always `0`, status message is
> always the empty byte sequence, header list is always empty, body is always
> null, and trailer is always empty.  
>  (引用元: [2.2.6. Responses - Fetch
> Standard](https://fetch.spec.whatwg.org/#concept-network-error))  
>  (引用元-日本語訳: [2.2.6. 応答 - Fetch Standard （日本語訳）](https://triple-
> underscore.github.io/Fetch-ja.html#concept-network-error))

"netword error" になる条件はいくつかありそうですが、軽く調べてみたところでは次のパターンがあります。

  * `XMLHttpRequest#abort()` した
  * HTTPリクエストが終了した
  * `XMLHttpRequest#open()` 実行後、変数 `response` に有効な値が代入されなかった(変数 `response` の初期値は "netword error")

Re: tetsuya さん
CC BY-SA 3.0
2017-07-14T13:54:36.513
36365
2017-07-14T13:54:36.513
20262
36352
answer
サーバー側の設定を変更することで解決できました。  
サーバはAmazon API Gatewayを使用しており、カスタムオーソライザーで弾かれた場合、Access-Control-Allow-
Origi‌​nヘッダーがレスポンスに付与されないため‌​、問題が生じていたようです。

以下のフォーラムで議論されています:  
[https://forums.aws.amazon.com/thread.jspa?threadID=228211&start=25&tstart=0](https://forums.aws.amazon.com/thread.jspa?threadID=228211&start=25&tstart=0)

フォーラムの回答で先月このユースケースに対応した旨の記載があったため、以下ドキュメントを参考に設定を試したところ、認証エラー時に401を取得することができました。  
<http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/customize-
gateway-responses.html#supported-gateway-response-types>
CC BY-SA 3.0
2017-07-21T07:50:18.333
36561
2017-07-21T07:50:18.333
22993
36352
answer