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文の実行プロセスの詳細な説明

推薦する

このリファレンスとJavaScriptのカスタムプロパティの詳細な説明

目次1. このキーワード2. カスタム属性3. 包括的なケース1:タブの実装付録要約する1. このキ...

ページ内のリストプルダウン効果を実現するための純粋なCSS

次のような効果がよく見られます。 そうです、ページ上でよく使われる「展開と折りたたみ」のインタラクシ...

CSSレイアウトにおけるフローティング問題に対する4つの解決策の詳細な説明

1. 原因:サブボックスをフロートに設定した後の効果: 青いボックスをフロートに設定すると、標準のド...

MySQLで行または列をソートする方法

方法:説明: どちらも達成できません:方法1: sp_product から sp.productid...

js を使用してファイルが UTF-8 でエンコードされているかどうかを判断する方法

従来の解決策FileReader を使用して UTF-8 形式のファイルを読み取り、ファイルの内容に...

EF (Entity Framework) の挿入または更新データ エラーの解決方法

エラー メッセージ:ストアの更新、挿入、または削除ステートメントが予期しない行数 (0) に影響を与...

フロントエンド HTML+CSS+JS を使用してシンプルな TODOLIST 関数を開発する (メモ帳)

目次1. 簡単な紹介2. スクリーンショットを実行する3. コードの紹介4. まとめ1. 簡単な紹介...

VMware で Nginx+KeepAlived クラスタ デュアルアクティブ アーキテクチャを展開する際の問題と解決策

序文負荷分散には nginx を使用します。アーキテクチャのフロントエンドまたは中間層として、トラフ...

Dockerコンテナが停止できない問題の解決方法

解決策は次のとおりです。 1. コンテナを強制削除する docker rm -f ジェンキンス2. ...

Vueはミックスインを使用してコンポーネントを最適化します

目次ミックスインの実装フック関数のマージプロジェクト実践伸ばす要約するVue は mixins AP...

MySQLプリコンパイル機能の詳細な説明

この記事では、MySQLのプリコンパイル機能について紹介します。具体的な内容は以下のとおりです。 1...

MySQL 8.0.24 のインストールと設定方法のグラフィックチュートリアル

この記事では、MySQL 8.0.24のインストールチュートリアルを参考までに紹介します。具体的な内...

MySQLとPythonの相互作用の例

目次1. データを準備するデータテーブルを作成するデータの挿入2. SQLドリル1. SQL文の強化...

MySQL が外部キーを作成できない理由と解決策

2 つのテーブルを関連付けるときに、外部キーを作成できませんでした。このブログから、問題は、ポイント...

Dockerを使用してクローンリポジトリを使用してGitイメージを構築する

概要私は 1 年以上 Docker を使用しています。最近、サービスをすばやくオーケストレーションし...