web-dev-qa-db-ja.com

HTTPステータスコード0には意味がありますか?

ブラウザでスクリプトからXMLHttpRequestを作成するとき、ブラウザがオフラインで動作するように設定されている場合、またはネットワークケーブルが引き出されている場合、リクエストはエラーで完了し、ステータス= 0になります。 HTTPステータスコード。

ステータスコード0はどういう意味ですか?すべてのブラウザで、すべてのHTTPクライアントユーティリティで同じことを意味しますか? HTTP仕様の一部ですか、それとも他のプロトコル仕様の一部ですか?おそらくサーバーアドレスを解決できなかったために、HTTPリクエストをまったく作成できなかったようです。

ユーザーに表示するのに適切なエラーメッセージは何ですか? 「インターネットに接続していないか、ウェブサイトで問題が発生しているか、アドレスに入力エラーがある可能性があります」

これに追加する必要があります。「Work Offline」に設定されている場合はFireFoxで動作しますが、「Work Offline」に設定されている場合はMicrosoft Internet Explorerでは動作しません。 IEでは、ユーザーはダイアログを表示して、オンラインにするオプションを提供します。 FireFoxは、エラーを返す前にユーザーに通知しません。

「より良いエラーメッセージを表示する」というリクエストへの応答としてこれを求めています。 Internet Explorerの機能は優れています。問題の原因をユーザーに伝え、それを修正するオプションを提供します。 FireFoxで同等のUXを提供するには、問題の原因を推測してユーザーに通知する必要があります。では、ステータス0から合計で何を推測できますか?それは普遍的な意味を持っていますか、それとも何も教えてくれませんか?

86
Mark Lutton

簡潔な答え

それはnot HTTP応答コードですが、isは、statusXMLHttpRequest属性の有効な値としてW3によって文書化されています(したがって、jQueryユーザーの場合はjqXHRオブジェクトの) )。

リクエストを送信していない、明示的に中止した、ページがアンロードされている、またはx行ったために、報告可能な実際のHTTP応答コードがない状況の全体を網羅しています。 xの多くの可能な値の1つに対して間違っています。

ロングアンサー

繰り返しますが、0はnot HTTPステータスコードです。 RFC 7231セクション6.1 にそれらの完全なリストがあります。これには0は含まれず、セクション6のイントロには次のように明記されています。

Status-code要素は3桁の整数コードです

どの0はそうではありません。

ただし、statusオブジェクトのXMLHttpRequest属性の値として0 is文書化されています。 http://www.w3.org/TR/XMLHttpRequest/#the-status-attribute のドキュメントから:

4.7.1ステータス属性

status属性は、これらのステップの実行結果を返す必要があります。

  1. 状態がUNSENTまたはOPENEDの場合、0を返します。

  2. エラーフラグが設定されている場合、0を返します。

  3. HTTPステータスコードを返します。

仕様をさらに掘り下げ、0を返すためのこれらの条件が何を意味するかを調べます。から http://www.w3.org/TR/XMLHttpRequest/#states

4.5州

...

UNSENT(数値0)

オブジェクトが構築されました。

OPENED(数値1)

open()メソッドが正常に呼び出されました。この状態の間、リクエストヘッダーはsetRequestHeader()を使用して設定でき、リクエストはsend()メソッドを使用して作成できます。

...

エラーフラグは、何らかのタイプのネットワークエラーまたはフェッチの終了を示します。最初は設定されていません。

また、UNSENTおよびOPENEDの後の次の可能な状態はHEADERS_RECEIVEDであることに注意することも重要です。

HEADERS_RECEIVED(数値2)

すべてのリダイレクト(存在する場合)が追跡され、最終応答のすべてのHTTPヘッダーが受信されました。オブジェクトのいくつかの応答メンバーが利用可能になりました。

これをまとめると、簡単な答えは、返される実際のステータスコードがない場合、0はstatusオブジェクトのXMLHttpRequest属性によって返されるものです。

  • リクエストがまだ送信されていない、または
  • 要求は送信されたが、応答のヘッダーがまだ受信されていない、または
  • ドキュメント にリストされている多くの考えられる状況の1つが発生し、「エラーフラグ」が設定されました。

わかりましたが、このミステリアスな「エラーフラグ」が設定される原因となるエラーは何ですか? W3ドキュメントの「エラーフラグ」でCTRL-Fを押すと、リクエストの送信時にnsetが取得され、setの一部としてのみ取得されることがわかります。 「リクエストを終了する」アルゴリズム。すべての場所を探しますthatアルゴリズムが呼び出された場合、次の場合に発生することがわかります。

  • リクエストはopen()メソッドで開かれます(または再び開かれます)
  • リクエストはガベージコレクションされます(ページを離れるときなど)
  • リクエストはabort()メソッドで中止されます
  • 次のいずれかの状況が発生すると、「リクエストエラー」が発生します。

    • ネットワークエラーが発生します。

      • 無限リダイレクトループがあります
      • あり/あり

        DNSエラー、TLSネゴシエーションの失敗、またはその他の種類のネットワークエラー

      • 要求はCORS要求であり、応答は共有できません
    • 中止エラーが発生します。これは、次の場合にのみ発生します。

      エンドユーザーがリクエストをキャンセルします

      それがどのような意味でも。 AJAXリクエストの発生時にユーザーを表示し、それらを明示的にキャンセルする機会を与えるブラウザを知らないので、これは-少なくとも今日-無関係であると思います。

    • タイムアウトエラーが発生します。

      timeout は0ではなく、リクエストが開始されてからtimeoutで指定されたミリ秒単位の時間が経過した

XMLHttpRequestに関する限り、それがすべてです。

XMLHttpRequestを超えて、JavaScript以外の言語のHTTPライブラリは、サーバーからステータスコードを受け取っていない場合のデフォルト値として、同様に0ステータスコードを使用していると推測します。

145
Mark Amery

ページを更新するか、到達不能なURLを要求して応答を取得する前にajax呼び出しがキャンセルされた場合、ステータス0が表示されます。

このステータスは文書化されていませんが、gadget.ioからのajaxおよびmakeRequest呼び出しに存在します。

52
mnk

ドキュメントから http://www.w3.org/TR/XMLHttpRequest/#the-status-attribute は、どこかに行く前にリクエストがキャンセルされたことを意味します

5
Loki

古い投稿であることを知ってください。しかし、これらの問題はまだ存在しています。

このテーマに関する私の調査結果のいくつかを、大まかに説明します。

「ステータス」0は、XMLHttpRequest仕様に従って、次の3つのいずれかを意味します。

  • dNS名前解決に失敗しました(たとえば、ネットワークプラグが抜かれたとき)

  • サーバーが応答しなかった(別名、到達不能または応答なし)

  • cORSの問題が原因でリクエストは中止されました(中止はユーザーエージェントによって実行され、失敗したOPTIONSプリフライトの後に続きます)。

さらに詳しく知りたい場合は、XMLHttpRequestの内部を深く掘り下げてください。準備完了状態の更新シーケンスを読むことをお勧めします([0,1,2,3,4]は通常のシーケンス、[0,1,4]はステータス0に対応し、[0,1,2,4]はコンテンツなしを意味します)送信されますが、エラーであるかどうかはわかりません)。詳細を把握するために、リスナーをxhr(onreadystatechange、onabort、onerror、ontimeout)にアタッチすることもできます。

仕様から( XHR Living spec ):

const unsigned short UNSENT = 0;
const unsigned short OPENED = 1;
const unsigned short HEADERS_RECEIVED = 2;
const unsigned short LOADING = 3;
const unsigned short DONE = 4;
4
Obotor

IOS 9以降、「App Transport Security Settings」をinfo.plistファイルに追加し、非セキュアHTTP Webサービスにリクエストを行う前に「Allow Arbitrary Loads」を許可する必要があります。アプリの1つでこの問題が発生しました。

0
Nirav