axios でリクエストをキャンセルし、重複リクエストを防ぐ方法について簡単に説明します。

axios でリクエストをキャンセルし、重複リクエストを防ぐ方法について簡単に説明します。

序文

実際のプロジェクトでは、リクエストに対して「手ぶれ防止」処理を実行する必要がある場合があります。これは主に、特定の状況下でユーザーが短時間にボタンを繰り返しクリックして、フロントエンドがバックエンドに複数のリクエストを繰り返し送信するのを防ぐためです。ここでは、よくある 2 つの実際的な状況を挙げます。

  • PC側 - 検索ボタンをダブルクリックすると、2つの検索要求がトリガーされる可能性があります
  • モバイル端末 - モバイル端末ではクリック遅延がないため、誤操作や多重操作が発生しやすく、リクエストの再送信が発生します。

読み込みマスクがある場合でも上記の状況が発生する可能性があるため、フロントエンドで重複したリクエストを防ぐ方法を検討する必要があります。

コア - キャンセルトークン

Axios でリクエストをキャンセルする中心的な方法は CanelToken です。公式ウェブサイトのドキュメントには、CancelTokenを使用する方法が2つ記載されています。ここでは、簡単な貼り付けとコメントの追加方法を紹介します。

方法1:

CancelToken は axios.CancelToken に置き換えられます。
const ソース = CancelToken.source();

axios.get('/user/12345', {
  //リクエストにはCancelTokenを設定する必要があります cancelToken: source.token
}).catch(関数(スロー) {
  // リクエストがキャンセルされた場合は、このメソッドに入り、(axios.isCancel(thrown)) かどうかを判断します。
    console.log('リクエストがキャンセルされました', throwed.message);
  } それ以外 {
    // エラーを処理する
  }
});

// 上記のリクエストをキャンセルします // source.cancel('messge') message はオプションであり、文字列である必要があります
source.cancel('ユーザーによって操作がキャンセルされました。');

方法2:

CancelToken は axios.CancelToken に置き換えられます。
キャンセルする;

axios.get('/user/12345', {
  // オプションで直接 cancelToken オブジェクトを作成します cancelToken: new CancelToken(function executor(c) {
    キャンセル = c;
  })
});

// 上記のリクエストをキャンセルします cancel();

実用的なアプリケーションとパッケージング

上記では axios のコアメソッドを例示しましたが、実際には公式ウェブサイトの例のようにこれらを使用することはほとんどありません。代わりに、axios インターセプターでグローバル構成管理を行います。この場合、上記のコードにいくつか変更を加える必要があります。

私が実装した一般的なアイデアは次のとおりです。

  • 進行中のすべてのリクエストをキャッシュする必要があります。リクエストを開始する前に、キャッシュ リスト内でリクエストが進行中かどうかを確認します。進行中の場合は、リクエストをキャンセルします。
  • リクエストが完了したら、リクエストを再送信できるようにキャッシュリストからリクエストを削除する必要があります。

アイデアが完成したら、すぐにコードに取り掛かりましょう

// 進行中のリクエストのリスト let reqList = []

/**
 * 重複リクエストを防止* @param {array} reqList - リクエストキャッシュリスト* @param {string} url - 現在のリクエストアドレス* @param {function} cancel - リクエスト中断関数* @param {string} errorMessage - リクエストが中断されたときに表示されるエラーメッセージ*/
const stopRepeatRequest = 関数 (reqList、url、cancel、errorMessage) {
  const errorMsg = エラーメッセージ || ''
  (i = 0 とします; i < reqList.length; i++) {
    if (reqList[i] === url) {
      キャンセル(エラーメッセージ)
      戻る
    }
  }
  reqList.push(url)
}

/**
 * リクエストの続行を許可する * @param {array} reqList すべてのリクエストのリスト * @param {string} url リクエストアドレス */
const allowRequest = 関数 (reqList, url) {
  (i = 0 とします; i < reqList.length; i++) {
    if (reqList[i] === url) {
      要求リスト.splice(i, 1)
      壊す
    }
  }
}

const サービス = axios.create()

// リクエストインターセプター service.interceptors.request.use(
  設定 => {
 キャンセルする
   // cancelToken オブジェクトを設定する config.cancelToken = new axios.CancelToken(function(c) {
     キャンセル = c
    })
    // 重複したリクエストを防ぎます。前のリクエストが完了していない場合、同じリクエストは停止されませんRepeatRequest(reqList, config.url, cancel, `${config.url} request is interrupted`)
    設定を返す
  },
  エラー => Promise.reject(エラー)
)

// レスポンスインターセプター service.interceptors.response.use(
  レスポンス => {
    // 遅延を増やします。同じリクエストが短期間に繰り返し送信されないようにする必要があります。setTimeout(() => {
      allowRequest(reqList、response.config.url) は、
    }, 1000)
    // ...リクエストが成功した後の後続の操作 // successHandler(response)
  },
  エラー => {
    もし(axios.isCancel(スロー)){
      console.log(スローされたメッセージ);
    } それ以外 {
      // 遅延を増やします。同じリクエストが短期間に繰り返し送信されないようにする必要があります。setTimeout(() => {
        allowRequest(reqList、error.config.url) は、
      }, 1000)
    }
    // ...リクエストが失敗した後の後続の操作 // errorHandler(error)
  }
)

いくつかの小さな詳細

上記の方法 2 のコードを使用して cancelToken を設定しなかったのはなぜですか?
axios のドキュメントには次のような注記があります:

注: 同じキャンセル トークンを使用して複数のリクエストをキャンセルできます。
同じトークンを使用して複数のリクエストをキャンセルできます。

したがって、各リクエストの前に新しいオブジェクトを作成したくありません。各キャンセルが正しく実行されるようにするには、必ず方法 2 を使用してください。前のメソッドでは、キャンセルが発生した後も後続のリクエストは引き続きキャンセルされます。

なぜ応答に遅延を追加する必要があるのでしょうか?
ユーザーが非常に短い期間内に同じリクエストを繰り返し行うことを望まないためです。
応答でリクエストをブロックすることと、リクエストでリクエストをブロックすることは、2 つの異なる概念であることに注意してください。
この要求は、前の要求が完了していない場合に同じ要求が再度開始されるのを防ぐためのものです。
この応答により、前のリクエストが完了してから一定期間内に同じリクエストが行われなくなります。

キャンセル時にメッセージだけでなくオブジェクトを渡すことはできますか?
公式インターフェースでは不可能です。公式ソースコードに従って再パッケージ化するか、サードパーティのプラグインを使用するか、別の方法(オブジェクトを JSON 文字列に変換し、必要に応じて再度変換する)を使用できます。

これで、axios でリクエストをキャンセルして重複リクエストを防ぐ方法についての記事は終了です。axios でリクエストをキャンセルして重複リクエストを防ぐ方法の詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Vue の Axios でリクエストをキャンセルし、重複リクエストを防ぐ方法

<<:  Zabbix で監視項目と集約されたグラフを設定するためのサンプルコード

>>:  mysql update文の実行プロセスの詳細な説明

推薦する

Nginx+Tomcat 負荷分散クラスタの実装例

目次導入1. 事例の概要2. 環境の展開3. Nginxホストのインストール4. Tomcatのイン...

HTML での一般的なリダイレクト接続の例コード

コードをコピーコードは次のとおりです。 window.location.href="zcb...

bashコマンドの使い方の詳細な説明

Linux では、基本的に vi エディタのように「.sh」拡張子を持つテキストの処理と実行を記述す...

Linux でディスクをマウントし、起動時に自動的にマウントするように設定する方法

皆さんの時間は貴重だと承知しているので、プロセス コマンドを直接書き留めておきます。設定できます。原...

MySQLはテーブル内のフィールドを別のテーブル内のフィールドの値と等しくなるように更新します

以下のように表示されます。 table1 を z として更新し、table2 を zb として結合し...

Tomcatでcatalina.batがUTF-8に設定されている場合、コンソールに文字化けした文字が表示されます

1. catalina.bat は UTF-8 に設定する必要があります。UTF-8 に設定しないと...

HTML の基本 - ハイパーリンク スタイルを設定する簡単な例

*** ハイパーリンクのスタイル設定の例a:link クリックされる前のハイパーリンクの状態a:vi...

Nginx アクセス ログとエラー ログ パラメータの説明

例: nginx ログには、アクセス ログとエラー ログの 2 つの主な種類があります。アクセス ロ...

Debian 9 システムに MySQL データベースをインストールする方法

序文タイトルを見ると、誰もが「Debian 9 に MySQL をインストールするにはどうすればいい...

動的なデジタル時計を実装するJavaScript

この記事では、JavaScriptで動的なデジタル時計を実装するための具体的なコードを参考までに紹介...

Docker はクラスター MongoDB 実装手順を構築します

序文会社の業務上のニーズにより、独自の MongoDB サービスを構築する予定です。MongoDB ...

VMware Workstation のダウンロードとインストールの詳細なチュートリアル

仮想マシンは非常に便利なテストソフトウェアです。ハードウェアに損傷を与えることなく、さまざまなテスト...

Dockerはコンテナに入るためにnsenterツールを使用する

Dockerコンテナを使用する場合は、nsenterツールを使用する方が便利です。システムにない場合...

Windows Server 2016 に MySQL 5.7.19 の解凍バージョンをインストールするための詳細なチュートリアル

MySQL 5.7.19 winx64 解凍版のインストールチュートリアルを収録しています。具体的な...

MySQL ベースのストレージエンジンとログの説明 (包括的な説明)

1.1 ストレージエンジンの概要 1.1.1 ファイルシステムストレージファイル システム: オペ...