XMLHttpRequest オブジェクト

導入

ブラウザとサーバー間の通信には HTTP プロトコルが使用されます。ユーザーがブラウザのアドレス バーに URL を入力するか、Web フォームを通じてコン​​テンツをサーバーに送信すると、ブラウザはサーバーに対して HTTP リクエストを作成します。

1999 年、Microsoft は IE ブラウザ バージョン 5.0 をリリースしました。このバージョンでは、JavaScript スクリプトがサーバーへの HTTP リクエストを開始できるようにするという新機能が初めて導入されました。この機能は当時は注目を集めませんでしたが、2004 年に Gmail がリリースされ、2005 年に Google マップがリリースされてから広く注目を集めました。 AJAX という言葉は、2005 年 2 月に初めて正式に提案されました。これは、Asynchronous JavaScript and XML の略で、JavaScript を介してサーバーから XML ドキュメントを取得し、そこからデータを抽出して更新することを指します。現在の Web ページの対応する部分を表示します。Web ページ全体を更新する必要はありません。その後、AJAX という言葉は、JavaScript スクリプトによって開始される HTTP 通信と同義になりました。つまり、通信を開始するためにスクリプトが使用される限り、それは AJAX 通信と呼ぶことができます。 W3C も 2006 年に国際標準を発表しました。

具体的には、AJAX には次の手順が含まれます。

  1. XMLHttpRequest インスタンスを作成する
  2. HTTPリクエストを行う
  3. サーバーから返されたデータを受信する 1.Webページデータの更新

一言でまとめると、AJAX はネイティブの「XMLHttpRequest」オブジェクトを通じて HTTP リクエストを発行し、サーバーから返されたデータを処理します。現在、サーバーは JSON 形式でデータを返し、XML 形式は廃止されましたが、AJAX という名前は一般名詞になり、文字通りの意味はなくなりました。

XMLHttpRequest オブジェクトは AJAX のメイン インターフェイスであり、ブラウザとサーバー間の通信に使用されます。名前には「XML」と「Http」が含まれていますが、実際には複数のプロトコル (「file」や「ftp」など) を使用して、任意の形式 (文字列やバイナリを含む) でデータを送信できます。

XMLHttpRequest 自体はコンストラクターであり、new コマンドを使用してインスタンスを生成できます。パラメータはありません。

var xhr = 新しい XMLHttpRequest();

インスタンスが作成されたら、「open()」メソッドを使用して、HTTP 接続を確立するための詳細を指定できます。

xhr.open('GET', 'http://www.example.com/page.php', true);

上記のコードは、指定されたサーバー URL との接続を確立するための GET メソッドの使用を指定します。 3 番目のパラメータ「true」は、リクエストが非同期であることを示します。

次に、通信状態の変化を監視するコールバック関数(readyState属性)を指定します。

xhr.onreadystatechange = handleStateChange;

関数 handleStateChange() {
  // ...
}

上記のコードでは、XMLHttpRequest インスタンスの状態が変化すると、リスニング関数 handleStateChange が呼び出されます。

最後に、send() メソッドを使用して実際にリクエストを行います。

xhr.send(null);

上記のコードでは、「send()」のパラメータは「null」です。これは、リクエストがデータ本体なしで送信されることを意味します。 POSTリクエストを送信する場合は、ここでデータ本体を指定する必要があります。

サーバーから返されたデータが取得されると、AJAX は Web ページ全体を更新せず、ユーザーの操作を中断しないように Web ページの関連部分のみを更新します。

AJAX は同じオリジン URL (プロトコル、ドメイン名、およびポートが同じ) に対してのみ HTTP リクエストを行うことができることに注意してください。クロスドメインリクエストが行われると、エラーが報告されます (「同一オリジンポリシー」の章を参照)。詳細については「CORS 通信」を参照してください)。

以下は、XMLHttpRequest オブジェクトの簡単な使用法の完全な例です。

var xhr = 新しい XMLHttpRequest();

xhr.onreadystatechange = function(){
  // 通信成功時のステータス値は4
  if (xhr.readyState === 4){
    if (xhr.status === 200){
      console.log(xhr.responseText);
    } それ以外 {
      console.error(xhr.statusText);
    }
  }
};

xhr.onerror = 関数 (e) {
  console.error(xhr.statusText);
};

xhr.open('GET', '/endpoint', true);
xhr.send(null);

XMLHttpRequest のインスタンス プロパティ

XMLHttpRequest.readyState

XMLHttpRequest.readyState は、インスタンス オブジェクトの現在の状態を表す整数を返します。このプロパティは読み取り専用です。次の値が返される場合があります。

  • 0。XMLHttpRequest インスタンスが生成されたが、インスタンスの open() メソッドが呼び出されなかったことを示します。
  • 1。 open() メソッドが呼び出されたが、インスタンスの send() メソッドがまだ呼び出されていないことを示します。インスタンスの setRequestHeader() メソッドを使用して、 HTTPリクエストのヘッダ情報。
  • 2。インスタンスの send() メソッドが呼び出され、サーバーから返されたヘッダー情報とステータス コードが受信されたことを示します。
  • 3、サーバーからのデータ本体(ボディ部)を受信中であることを示します。このとき、インスタンスの「responseType」プロパティが「text」または空文字列の場合、「responseText」プロパティには受信した情報の一部が含まれます。
  • 4、サーバーから返されたデータが完全に受信されたか、受信が失敗したことを示します。

通信プロセス中に、インスタンス オブジェクトの状態が変化するたびに、その readyState 属性の値が変化します。この値が変更されるたびに、readyStateChange イベントがトリガーされます。

var xhr = 新しい XMLHttpRequest();

if (xhr.readyState === 4) {
//リクエストが終了し、サーバーから返されたデータが処理されます。
} それ以外 {
// プロンプト「読み込み中...」を表示します。
}

上記のコードで、「xhr.readyState」が「4」に等しい場合、スクリプトによって発行された HTTP リクエストが完了したことを示します。他の場合は、HTTP リクエストがまだ進行中であることを意味します。

XMLHttpRequest.onreadystatechange

XMLHttpRequest.onreadystatechange 属性は、リスニング関数を指します。このプロパティは、readystatechange イベントが発生したとき (インスタンスの readyState プロパティが変化したとき) に実行されます。

さらに、インスタンスの abort() メソッドを使用して XMLHttpRequest リクエストを終了すると、readyState 属性も変更され、XMLHttpRequest.onreadystatechange 属性が呼び出されます。

以下に例を示します。

var xhr = 新しい XMLHttpRequest();
xhr.open( 'GET', 'http://example.com' , true );
xhr.onreadystatechange = function () {
  if (xhr.readyState !== 4 || xhr.status !== 200) {
    戻る;
  }
  console.log(xhr.responseText);
};
xhr.send();

XMLHttpRequest.response

XMLHttpRequest.response プロパティは、サーバーから返されたデータ本体 (つまり、HTTP 応答の本体部分) を表します。文字列、オブジェクト、バイナリ オブジェクトなど、任意のデータ型を使用できます。特定の型は、XMLHttpRequest.responseType プロパティによって決定されます。このプロパティは読み取り専用です。

このリクエストが失敗した場合、またはデータが不完全な場合、この属性は「null」と等しくなります。ただし、responseType 属性が text または空の文字列に等しい場合、リクエストが完了する前 (readyState が 3 に等しい段階)、response 属性には返されたデータの一部が含まれます。サーバーによって。

var xhr = 新しい XMLHttpRequest();

xhr.onreadystatechange = function () {
  if (xhr.readyState === 4) {
    ハンドラー(xhr.response);
  }
}

XMLHttpRequest.responseType

XMLHttpRequest.responseType 属性は、サーバーから返されるデータのタイプを示す文字列です。この属性は書き込み可能です。open() メソッドを呼び出した後、send() メソッドを呼び出す前に、この属性の値を設定して、返されたデータの解釈方法をブラウザーに指示できます。 responseType が空の文字列に設定されている場合、それはデフォルト値の text と同等です。

XMLHttpRequest.responseType 属性は次の値と等しくなります。

  • "" (空の文字列): text と同等で、サーバーがテキスト データを返すことを示します。
  • "arraybuffer": ArrayBuffer オブジェクト。サーバーがバイナリ配列を返すことを示します。
  • "blob": BLOB オブジェクト。サーバーがバイナリ オブジェクトを返すことを示します。
  • "document": ドキュメント オブジェクト。サーバーがドキュメント オブジェクトを返すことを示します。
  • "json": JSON オブジェクト。
  • 「テキスト」: 文字列。

上記のタイプのうち、text タイプはほとんどの状況に適しており、テキストを直接処理する方が便利です。 「document」タイプは、HTML/XML ドキュメントを返すのに適しています。つまり、CORS を有効にする Web サイトでは、Ajax を直接使用して Web ページをクロールし、HTML を解析せずにキャプチャされたデータに対して DOM 操作を直接実行できます。弦。 blob タイプは、画像ファイルなどのバイナリ データの読み取りに適しています。

var xhr = 新しい XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = 'ブロブ';

xhr.onload = 関数(e) {
  if (this.status === 200) {
    var blob = 新しい Blob([xhr.response], {type: 'image/png'});
    // または
    var blob = xhr.response;
  }
};

xhr.send();

このプロパティを ArrayBuffer に設定すると、バイナリ データを配列として処理できます。

var xhr = 新しい XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = '配列バッファ';

xhr.onload = 関数(e) {
  var uInt8Array = 新しい Uint8Array(this.response);
  for (var i = 0, len = uInt8Array.length; i < len; ++i) {
    // var byte = uInt8Array[i];
  }
};

xhr.send();

この属性が「json」に設定されている場合、ブラウザは返されたデータに対して自動的に「JSON.parse()」メソッドを呼び出します。つまり、xhr.response プロパティ (xhr.responseText プロパティではないことに注意してください) から取得するものはテキストではなく、JSON オブジェクトです。

XMLHttpRequest.responseText

XMLHttpRequest.responseText プロパティは、サーバーから受信した文字列を返します。このプロパティは読み取り専用です。この属性には、HTTP リクエストが受信された後にのみ完全なデータが含まれます。

var xhr = 新しい XMLHttpRequest();
xhr.open('GET', '/server', true);

xhr.responseType = 'テキスト';
xhr.onload = 関数 () {
  if (xhr.readyState === 4 && xhr.status === 200) {
    console.log(xhr.responseText);
  }
};

xhr.send(null);

XMLHttpRequest.responseXML

XMLHttpRequest.responseXML プロパティは、サーバーから受信した HTML または XML ドキュメント オブジェクトを返します。このプロパティは読み取り専用です。リクエストが失敗した場合、または受信したデータを XML または HTML として解析できない場合、この属性は「null」に等しくなります。

この属性が有効になるための前提条件は、HTTP 応答の Content-Type ヘッダー情報が text/xml または application/xml と等しいことです。これには、リクエストを送信する前に XMLHttpRequest.responseType プロパティを document に設定する必要があります。 HTTP レスポンスの「Content-Type」ヘッダー情報が「text/xml」および「application/xml」と等しくないが、「responseXML」からデータを取得したい場合(つまり、DOM に従ってデータを解析する) format) の場合は、「XMLHttpRequest」を手動で呼び出す必要があります。 .overrideMimeType()` メソッドは XML 解析を強制します。

この属性によって取得されるデータは、直接解析されたドキュメント DOM ツリーです。

var xhr = 新しい XMLHttpRequest();
xhr.open('GET', '/server', true);

xhr.responseType = 'ドキュメント';
xhr.overrideMimeType('text/xml');

xhr.onload = 関数 () {
  if (xhr.readyState === 4 && xhr.status === 200) {
    console.log(xhr.responseXML);
  }
};

xhr.send(null);

XMLHttpRequest.responseURL

XMLHttpRequest.responseURL 属性は、データを送信するサーバーの URL を表す文字列です。

var xhr = 新しい XMLHttpRequest();
xhr.open('GET', 'http://example.com/test', true);
xhr.onload = 関数 () {
  // http://example.com/test に戻ります
  console.log(xhr.responseURL);
};
xhr.send(null);

この属性の値は、open() メソッドで指定されたリクエスト URL と必ずしも同じではないことに注意してください。サーバー側でジャンプが発生した場合、この属性は実際にデータを返す最後の URL を返します。さらに、元の URL にアンカー (フラグメント) が含まれている場合、このプロパティはアンカーを削除します。

XMLHttpRequest.status、XMLHttpRequest.statusText

XMLHttpRequest.status プロパティは、サーバーから応答された HTTP ステータス コードを表す整数を返します。一般に、通信が成功した場合、このステータス コードは 200 ですが、サーバーがステータス コードを返さない場合、この属性のデフォルトは 200 になります。リクエストが発行される前、この属性は「0」です。このプロパティは読み取り専用です。

  • 200、OK、アクセスは正常です
  • 301、永久に移動されました、永久に移動されました
  • 302、一時的に移動されました、一時的に移動されました
  • 304、未変更、未変更
  • 307、一時リダイレクト、一時リダイレクト
  • 401、不正、不正
  • 403、禁止、アクセス禁止
  • 404、Not Found、指定された URL が見つかりませんでした
  • 500、内部サーバーエラー、サーバーでエラーが発生しました

基本的に、ステータス コードは 2xx と 304 のみで、サーバーが正常なステータスを返したことを示します。

if (xhr.readyState === 4) {
if ( (xhr.status >= 200 && xhr.status < 300)
|| (xhr.status === 304) ) {
// サーバーから返されたデータを処理します
} それ以外 {
// エラー
}
}

XMLHttpRequest.statusText プロパティは、サーバーから送信されたステータス メッセージを表す文字列を返します。 「ステータス」属性とは異なり、この属性には「OK」や「見つかりません」などのステータス情報全体が含まれます。リクエストが送信される前 (つまり、open() メソッドが呼び出される前)、この属性の値は空の文字列です。サーバーがステータス プロンプトを返さない場合、この属性の値はデフォルトで "OK" になります。 」。このプロパティは読み取り専用です。

XMLHttpRequest.timeout、XMLHttpRequestEventTarget.ontimeout

XMLHttpRequest.timeout プロパティは、何ミリ秒後にリクエストが結果を取得しない場合に自動的に終了するかを示す整数を返します。この属性が 0 に等しい場合は、時間制限がないことを意味します。

XMLHttpRequestEventTarget.ontimeout 属性は、タイムアウト イベントが発生した場合にリスニング関数を設定するために使用されます。

以下に例を示します。

var xhr = 新しい XMLHttpRequest();
var URL = '/サーバー';

xhr.ontimeout = function () {
  console.error('「 + URL + 」のリクエストがタイムアウトしました。');
};

xhr.onload = function() {
  if (xhr.readyState === 4) {
    if (xhr.status === 200) {
      // サーバーから返されたデータを処理します
    } それ以外 {
      console.error(xhr.statusText);
    }
  }
};

xhr.open('GET', URL, true);
// 10秒のタイムアウトを指定します
xhr.timeout = 10 * 1000;
xhr.send(null);

イベントリスニングのプロパティ

XMLHttpRequest オブジェクトでは、次のイベントのリスニング関数を指定できます。

  • XMLHttpRequest.onloadstart:loadstartイベント(HTTPリクエスト発行)のリスニング機能
  • XMLHttpRequest.onprogress: 進行状況イベントのリスニング関数 (データの送信およびロード中)
  • XMLHttpRequest.onabort: 中止イベントのリスニング関数 (ユーザーによる abort() メソッドの呼び出しなどの中止要求)
  • XMLHttpRequest.onerror: エラーイベント(リクエスト失敗)のリスニング機能
  • XMLHttpRequest.onload: ロードイベントのリスニング関数(リクエストは正常に完了しました)
  • XMLHttpRequest.ontimeout: タイムアウトイベント(ユーザーが指定した制限時間を超え、リクエストが完了していない)のリスニング機能
  • XMLHttpRequest.onloadend:loadendイベントのリスニング関数(成功または失敗に関係なくリクエスト完了)

以下に例を示します。

xhr.onload = function() {
 var 応答テキスト = xhr.responseText;
 console.log(応答テキスト);
 // レスポンスを処理します。
};

xhr.onabort = function () {
  console.log('リクエストは中止されました');
};

xhr.onprogress = 関数 (イベント) {
  コンソール.ログ(イベント.ロード);
  コンソール.ログ(イベント.合計);
};

xhr.onerror = function() {
  console.log('エラーが発生しました!');
};

「progress」イベントのリスニング関数にはイベント オブジェクト パラメータがあり、これには 3 つのプロパティがあります。「loaded」プロパティは転送されたデータ量を返し、「total」プロパティはデータの総量を返し、「 lengthComputable` プロパティは、読み込みの進行状況を計算できるかどうかを示すブール値を返します。これらすべてのリスニング関数のうち、「progress」イベントのリスニング関数のみがパラメーターを持ち、他の関数にはパラメーターがありません。

ネットワークエラーが発生した場合(サーバーに接続できないなど)、onerror イベントはエラー情報を取得できないことに注意してください。つまり、エラーオブジェクトが存在しない可能性があるため、エラーメッセージのみを表示することができます。

XMLHttpRequest.withCredentials

XMLHttpRequest.withCredentials 属性はブール値で、クロスドメイン リクエストを行うときにユーザー情報 (Cookie や認証 HTTP ヘッダー情報など) をリクエストに含めるかどうかを示します。デフォルトは false です。 example.com へ クロスドメイン要求を行う場合、このマシン上の example.com によって設定された Cookie (存在する場合) は送信されません。

ドメイン AJAX リクエスト間で Cookie を送信する必要がある場合は、「withCredentials」属性を「true」に設定する必要があります。同じオリジンからのリクエストは、この属性を設定する必要がないことに注意してください。

var xhr = 新しい XMLHttpRequest();
xhr.open('GET', 'http://example.com/', true);
xhr.withCredentials = true;
xhr.send(null);

この属性を有効にするには、サーバーが Access-Control-Allow-Credentials ヘッダーを明示的に返す必要があります。

アクセス制御許可資格情報: true

withCredentials 属性がオンになっている場合、クロスドメイン要求は Cookie を送信するだけでなく、リモート ホストによって指定された Cookie も設定します。逆も同様です。「withCredentials」属性がオンになっていない場合、ブラウザーは明示的に Cookie の設定を要求している場合でも、クロスドメイン AJAX リクエストを無視します。

スクリプトは常に同一オリジン ポリシーに準拠し、「document.cookie」または HTTP 応答ヘッダーからクロスオリジン Cookie を読み取ることができないことに注意してください。「withCredentials」属性はこれに影響しません。

XMLHttpRequest.upload

XMLHttpRequest はリクエストだけでなくファイルも送信できます。これは AJAX ファイルのアップロードです。ファイルを送信した後、XMLHttpRequest.upload 属性を通じてオブジェクトを取得でき、このオブジェクトを観察することでアップロードの進行状況を知ることができます。主なメソッドは、このオブジェクトのさまざまなイベント (loadstart、loadend、load、abort、error、progress、timeout) を監視することです。

Web ページに <progress> 要素があるとします。

<progress min="0" max="100" value="0">0% 完了</progress>

ファイルをアップロードする際、アップロードの進捗状況を取得するためにupload属性にprogressイベントのlisten関数を指定します。

関数アップロード(blobOrFile) {
  var xhr = 新しい XMLHttpRequest();
  xhr.open('POST', '/server', true);
  xhr.onload = 関数 (e) {};

  var progressBar = document.querySelector('progress');
  xhr.upload.onprogress = 関数 (e) {
    if (e.lengthComputable) {
      progressBar.value = (e.loaded / e.total) * 100;
      // <progress> 要素をサポートしていない古いブラウザと互換性があります
      progressBar.textContent = progressBar.value;
    }
  };

  xhr.send(blobOrFile);
}

Upload(new Blob(['hello world'], {type: 'text/plain'}));

XMLHttpRequest のインスタンス メソッド

XMLHttpRequest.open()

XMLHttpRequest.open() メソッドは、HTTP リクエストのパラメータを指定するか、XMLHttpRequest インスタンス オブジェクトを初期化するために使用されます。合計 5 つのパラメータを受け入れることができます。

ボイドオープン(
   文字列メソッド、
   文字列URL、
   オプションのブール型非同期、
   オプションの文字列ユーザー、
   オプションの文字列パスワード
);
  • method: GETPOSTPUTDELETEHEADなどのHTTP動詞メソッドを表します。
  • url: ターゲット URL の送信リクエストを示します。
  • async: リクエストが非同期かどうかを示すブール値。デフォルトは true です。 「false」に設定すると、「send()」メソッドはサーバーから結果を受信するまで次のステップに進みません。このパラメータはオプションです。同期 AJAX リクエストはブラウザーの応答を失う原因となるため、多くのブラウザーはメインスレッドでの使用を禁止し、ワーカーでのみ使用を許可しています。したがって、このパラメータは決して「false」に設定しないでください。
  • user: 認証に使用されるユーザー名を示します。デフォルトは空の文字列です。このパラメータはオプションです。
  • password: 認証に使用されるパスワードを示します。デフォルトは空の文字列です。このパラメータはオプションです。

open() メソッドを使用した AJAX リクエストを作成した場合、このメソッドを再度使用することは、リクエストを終了することを意味する abort() を呼び出すことと同じであることに注意してください。

以下は POST リクエストの送信例です。

var xhr = 新しい XMLHttpRequest();
xhr.open('POST', encodeURI('someURL'));

XMLHttpRequest.send()

実際に HTTP リクエストを行うには、XMLHttpRequest.send() メソッドが使用されます。パラメータがない場合は、HTTP リクエストに URL が 1 つだけあり、データ本体がないことを意味します。パラメータがある場合は、ヘッダー情報に加えて、特定のデータを含む情報も含まれます。典型的な例は POST リクエストです。

以下は GET リクエストの例です。

var xhr = 新しい XMLHttpRequest();
xhr.open('GET',
  'http://www.example.com/?id=' + encodeURIComponent(id),
  真実
);
xhr.send(null);

上記のコードでは、「GET」リクエストのパラメータがクエリ文字列として URL に追加されます。

以下は POST リクエストの送信例です。

var xhr = 新しい XMLHttpRequest();
var data = '電子メール='
  + encodeURIComponent(メール)
  + '&パスワード='
  + encodeURIComponent(パスワード);

xhr.open('POST', 'http://www.example.com', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(データ);

すべての XMLHttpRequest リスニング イベントは、send() メソッドが呼び出される前に設定する必要があることに注意してください。

send メソッドのパラメータは送信されるデータです。パラメータとしてさまざまな形式のデータを使用できます。

void send();
void send(ArrayBufferView データ);
void send(Blob データ);
void send(文書データ);
void send(文字列データ);
void send(FormData データ);

send() が DOM オブジェクトを送信する場合、データは送信前にシリアル化されます。バイナリ データを送信する場合は、ArrayBufferView または Blob オブジェクトを送信することをお勧めします。これにより、Ajax 経由でファイルをアップロードできるようになります。

以下はフォームデータの送信例です。 FormData オブジェクトを使用してフォーム データを構築できます。

var formData = 新しい FormData();

formData.append('ユーザー名', '張三');
formData.append('電子メール', 'zhangsan@example.com');
formData.append('birthDate', 1940);

var xhr = 新しい XMLHttpRequest();
xhr.open('POST', '/register');
xhr.send(フォームデータ);

上記のコードでは、FormData オブジェクトがフォーム データを構築し、それを send() メソッドを使用して送信します。以下のフォームデータを送信するのと同じ効果があります。

<form id='登録' name='登録' action='/register'>
  <input type='text' name='username' value='Zhang San'>
  <input type='email' name='email' value='zhangsan@example.com'>
  <input type='number' name='birthDate' value='1940'>
  <input type='submit' onclick='return sendForm(this.form);'>
</form>

次の例では、FormData オブジェクトを使用してフォーム データを処理し、送信します。

関数 sendForm(フォーム) {
  var formData = 新しい FormData(form);
  formData.append('csrf', 'e69a18d7db1286040586e6da1950128c');

  var xhr = 新しい XMLHttpRequest();
  xhr.open('POST', form.action, true);
  xhr.onload = function() {
    // ...
  };
  xhr.send(フォームデータ);

  false を返します。
}

var form = document.querySelector('#registration');
sendForm(フォーム);

XMLHttpRequest.setRequestHeader()

XMLHttpRequest.setRequestHeader() メソッドは、ブラウザによって送信される HTTP リクエストのヘッダー情報を設定するために使用されます。このメソッドは、「open()」の後、「send()」の前に呼び出す必要があります。このメソッドが同じフィールドを設定するために複数回呼び出された場合、各呼び出しの値は 1 つの値に結合されて送信されます。

このメソッドは 2 つのパラメータを受け入れます。最初のパラメータはヘッダー情報のフィールド名を表す文字列で、2 番目のパラメータはフィールド値です。

xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Content-Length', JSON.stringify(data).length);
xhr.send(JSON.stringify(data));

上記のコードは、最初にヘッダー情報 Content-Type (データを JSON 形式で送信することを意味します) を設定し、次に Content-Length (データ長を意味します) を設定して、最後に JSON データを送信します。

XMLHttpRequest.overrideMimeType()

XMLHttpRequest.overrideMimeType() メソッドは、MIME タイプを指定し、サーバーから返された実際の MIME タイプをオーバーライドするために使用され、ブラウザがそれを別の方法で処理できるようにします。たとえば、サーバーから返されたデータ タイプが「text/xml」である場合、さまざまな理由により、ブラウザは解析に失敗し、データを取得できません。元のデータを取得するには、MIME タイプを「text/plain」に変更します。これにより、ブラウザが自動的に解析しないようにして、元のテキストを取得できます。

xhr.overrideMimeType('text/plain')

このメソッドは send() メソッドの前に呼び出す必要があることに注意してください。

サーバーから返されるデータ型を変更することは、通常の状況では実行すべき方法ではありません。サーバーに特定のデータ型を返してもらいたい場合は、以下の例のように、responseType 属性を使用してサーバーに伝えることができます。 overrideMimeType() メソッドは、サーバーが特定のデータ型を返せない場合にのみ使用してください。

var xhr = 新しい XMLHttpRequest();
xhr.onload = 関数(e) {
  var arraybuffer = xhr.response;
  // ...
}
xhr.open('GET', URL);
xhr.responseType = '配列バッファ';
xhr.send();

XMLHttpRequest.getResponseHeader()

XMLHttpRequest.getResponseHeader() メソッドは、HTTP ヘッダーの指定されたフィールドの値を返します。サーバーから応答が受信されない場合、または指定されたフィールドが存在しない場合は、null が返されます。このメソッドのパラメータでは大文字と小文字が区別されません。

関数 getHeaderTime() {
  console.log(this.getResponseHeader("Last-Modified"));
}

var xhr = 新しい XMLHttpRequest();
xhr.open('HEAD', 'yourpage.html');
xhr.onload = getHeaderTime;
xhr.send();

同じ名前のフィールドが複数ある場合、それらの値は文字列に連結され、各フィールドは「カンマ + スペース」で区切られます。

XMLHttpRequest.getAllResponseHeaders()

XMLHttpRequest.getAllResponseHeaders() メソッドは、サーバーから送信されたすべての HTTP ヘッダー情報を表す文字列を返します。形式は文字列であり、各ヘッダ情報は CRLF (キャリッジ リターン + ライン フィード) で区切られます。サーバーからの応答が受信されない場合、この属性は null になります。ネットワーク エラーが発生した場合、このプロパティは空の文字列になります。

var xhr = 新しい XMLHttpRequest();
xhr.open('GET', 'foo.txt', true);
xhr.send();

xhr.onreadystatechange = function () {
  if (this.readyState === 4) {
    var headers = xhr.getAllResponseHeaders();
  }
}

上記のコードは、サーバーから返されたすべてのヘッダー情報を取得するために使用されます。以下のような文字列になる場合があります。

日付: 2017 年 12 月 8 日金曜日 21:04:30 GMT\r\n
コンテンツ エンコーディング: gzip\r\n
x-content-type-options: nosniff\r\n
サーバー: meinheld/0.6.1\r\n
x-frame-options: 拒否\r\n
コンテンツタイプ: text/html; charset=utf-8\r\n
接続: キープアライブ\r\n
厳密なトランスポート セキュリティ: max-age=63072000\r\n
変更: Cookie、Accept-Encoding\r\n
コンテンツの長さ: 6502\r\n
x-xss-protection: 1; モード=ブロック\r\n

次に、この文字列を処理します。

var arr = headers.trim().split(/[\r\n]+/);
var headerMap = {};

arr.forEach(関数(行) {
  var Parts = line.split(': ');
  var ヘッダー = Parts.shift();
  var value = Parts.join(': ');
  headerMap[ヘッダー] = 値;
});

headerMap['content-length'] // "6502"

XMLHttpRequest.abort()

XMLHttpRequest.abort() メソッドは、送信された HTTP リクエストを終了するために使用されます。このメソッドを呼び出した後、readyState プロパティは 4 になり、status プロパティは 0 になります。

var xhr = 新しい XMLHttpRequest();
xhr.open('GET', 'http://www.example.com/page.php', true);
setTimeout(関数() {
if (xhr) {
xhr.abort();
xhr = null;
}
}, 5000);

上記のコードは、AJAX リクエストが発行されてから 5 秒後にそのリクエストを終了します。

XMLHttpRequest インスタンスのイベント

###readyStateChangeイベント

「readyState」プロパティの値が変更されると、readyStateChange イベントがトリガーされます。

onReadyStateChange 属性を通じてこのイベントのリッスン関数を指定して、さまざまな状態を異なる方法で処理できます。特にステータスが「4」に変わった場合は、通信が成功したことを意味します。この時点で、コールバック関数はサーバーから返されたデータを処理できます。

進捗イベント

ファイルをアップロードするとき、XMLHttpRequest インスタンス オブジェクト自体とインスタンスの upload 属性には、アップロードの進行状況を継続的に返す progress イベントがあります。

var xhr = 新しい XMLHttpRequest();

関数 updateProgress (oEvent) {
  if (oEvent.lengthComputable) {
    varpercentComplete = oEvent.loaded / oEvent.total;
  } それ以外 {
    console.log('進行状況を計算できません');
  }
}

xhr.addEventListener('進行状況', updateProgress);

xhr.open();

ロードイベント、エラーイベント、中止イベント

ロード イベントはサーバーからデータが受信されたことを示し、エラー イベントはリクエストが失敗したことを示し、中止イベントはリクエストが中断されたことを示します (たとえば、ユーザーがリクエストをキャンセルした)。

var xhr = 新しい XMLHttpRequest();

xhr.addEventListener('load', transferComplete);
xhr.addEventListener('error', transferFailed);
xhr.addEventListener('中止', transferCanceled);

xhr.open();

関数 transferComplete() {
  console.log('データ受信完了');
}

関数 transferFailed() {
  console.log('データ受信エラー');
}

関数 transferCanceled() {
  console.log('ユーザーが受信をキャンセル');
}

ロードエンドイベント

3 つのイベント「abort」、「load」、および「error」には、リクエストが終了したことを示す「loadend」イベントが伴いますが、成功したかどうかは不明です。

xhr.addEventListener('loadend',loadEnd);

関数loadEnd(e) {
  console.log('リクエストは終了しました、ステータスは不明です');
}

タイムアウトイベント

指定された時間内にサーバーが結果を返さなかった場合、タイムアウト イベントがトリガーされます。具体的な例については、「timeout」属性のセクションを参照してください。

Navigator.sendBeacon()

ユーザーが Web ページをアンインストールするとき、サーバーにデータを送信する必要がある場合があります。自然なアプローチは、「XMLHttpRequest」オブジェクトを使用して、「unload」イベントまたは「beforeunload」イベントのリスニング関数でデータを送信することです。ただし、「XMLHttpRequest」オブジェクトは非同期で送信され、送信しようとしたときにページがアンロードされ、送信がキャンセルまたは失敗する可能性があるため、これはあまり信頼できません。

解決策は、時間のかかる同期操作を「unload」イベントに追加することです。これにより、非同期 AJAX が正常に送信されることを確認するのに十分な時間が確保されます。

関数 log() {
  let xhr = 新しい XMLHttpRequest();
  xhr.open('post', '/log', true);
  xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  xhr.send('foo=bar');
}

window.addEventListener('アンロード', function(event) {
  ログ();

  // 時間のかかる操作
  for (let i = 1; i < 10000; i++) {
    for (m = 1; m < 10000; m++) { 続行 }
  }
});

上記のコードでは、二重ループが強制的に実行されるため、「unload」イベントの実行時間が長くなり、非同期 AJAX が正常に送信されます。

同様に、「setTimeout()」も使用できます。以下はユーザーのクリックを追跡する例です。

// HTMLコードは以下の通り
// <a id="target" href="https://baidu.com">クリック</a>
const clickTime = 350;
const theLink = document.getElementById('target');

関数 log() {
  let xhr = 新しい XMLHttpRequest();
  xhr.open('post', '/log', true);
  xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  xhr.send('foo=bar');
}

theLink.addEventListener('click', 関数 (イベント) {
  イベント.preventDefault();
  ログ();

  setTimeout(関数() {
    window.location.href = theLink.getAttribute('href');
  }、クリック時間);
});

上記のコードでは setTimeout() を使用しています。これにより、ジャンプする前にページを 350 ミリ秒遅延させ、非同期 AJAX の発行時間を与えます。

これらのアプローチに共通する問題は、アンインストール時間が長くなり、後続のページの読み込みが遅くなり、ユーザー エクスペリエンスが良くないことです。

この問題を解決するために、ブラウザは Navigator.sendBeacon() メソッドを導入しました。このメソッドでもリクエストは非同期で送信されますが、リクエストは現在のページ スレッドから切り離され、ブラウザ プロセスのタスクとなるため、アンインストール プロセスを遅らせることなくデータが送信されることが保証されます。

window.addEventListener('unload', logData, false);

関数 logData() {
  navigator.sendBeacon('/log', JSON.stringify({
    一部: 「データ」
  }));
}

Navigator.sendBeacon() メソッドは 2 つのパラメータを受け取ります。最初のパラメータはターゲット サーバーの URL で、2 番目のパラメータは送信するデータ (オプション) で、任意のタイプ (文字列、フォーム オブジェクト、バイナリオブジェクトなど)。

navigator.sendBeacon(url, data)

このメソッドの戻り値はブール値で、データが正常に送信された場合は「true」、それ以外の場合は「false」です。

このメソッドでデータを送信する HTTP メソッドは POST です。これはドメインを越えることができ、フォームでデータを送信するのと似ています。コールバック関数は指定できません。

以下に例を示します。

// HTMLコードは以下の通り
// <body onload="analytics('start')" onunload="analytics('end')">

関数分析(状態) {
  if (!navigator.sendBeacon) が戻る;

  var URL = 'http://example.com/analytics';
  var data = 'state=' + state + '&location=' + window.location;
  navigator.sendBeacon(URL, データ);
}

このメソッドではカスタム HTTP ヘッダーは許可されません。データを「application/json」として送信するには、Blob オブジェクトを使用できます。

const blob = 新しい Blob(
  [ JSON.stringify({ some: "データ" }) ],
  { タイプ: 'アプリケーション/json=UTF-8' }
);
navigator.sendBeacon('/log', blob));

このメソッドの優先順位は低く、ページ リソースを占有しません。通常、ブラウザがアイドル状態のときに送信されます。


作者: wangdoc

アドレス: https://wangdoc.com/

ライセンス: クリエイティブ・コモンズ 3.0