記事ディレクトリ
シーン
ユーザーが新しい操作 (メニューの追加など) を実行しています。[追加] ボタンをすばやく複数回クリックすると、複数のレコードが追加される場合があります。通常、新しいボタンをクリックするとまずそのボタンを無効にし、この操作が完了した後にロックを解除します。ただし、axios を使用してより洗練された実装方法があります。
Axios の重複投稿防止
一連の考え
まずアイデアについて話しましょう。axios 送信操作を実行するときに、このリクエストにマークを付けて配列に保存します。リクエストが終了したら、この配列からリクエスト タグを削除します。したがって、同一のリクエストが 2 つある場合、後続のリクエストではマークがこの配列にすでに存在していることがわかり、axios でこのリクエストがキャンセルされます。
実装
私のコードでは、axios は http.js で均一にカプセル化されているため、http.js で実装するだけで済みます。まず、
リクエスト タグを格納する配列を定義し、キャンセル axios リクエスト オブジェクトを定義します。
// 请求列表(防重复提交)
let requestList = [];
let cancelToken = axios.CancelToken;
次に、リクエスト タグを決定します。ここでは、リクエスト インターセプタで、リクエストされた URL + リクエスト パラメータ + リクエスト メソッドを文字列に組み合わせてリクエスト タグとして使用します。コードは次のとおりです。
axios.interceptors.request.use(
config => {
//防止重复提交(如果本次是重复操作,则取消,否则将该操作标记到requestList中)
config.cancelToken = new cancelToken((cancel) => {
let requestFlag = JSON.stringify(config.url) + JSON.stringify(config.data) + '&' + config.method;
if (requestList.includes(requestFlag)) {
//请求标记已经存在,则取消本次请求,否则在请求列表中加入请求标记
cancel();//取消本次请求
} else {
requestList.push(requestFlag);
}
});
return config;
},
error => {
return Promise.reject(err);
}
);
最後に、リクエストの最後にマークの削除をリクエストしてください。レスポンス インターセプタのコードは次のとおりです。
axios.interceptors.response.use(
response => {
//请求返回后,将请求标记从requestList中移除
let requestFlag = JSON.stringify(response.config.url) + JSON.stringify(response.config.data) + '&' + response.config.method;
requestList.splice(requestList.findIndex(item => item === requestFlag), 1);
return response;
},
error => {
//置空请求列表
requestList.length = 0;
return Promise.reject(error)
}
)
補充する
システム内に、同じ URL、パラメータ、リクエスト メソッドを持つ 2 つのリクエストと、ユーザーの操作でバックエンドへのリクエストが実際に存在する場合 (そのような状況に遭遇したことはありません)、この方法による解決策もあります。上記の導入では、リクエスト タグは次の方法で使用されます: URL+リクエスト パラメータ+リクエスト メソッド。そして、このときのリクエストパラメータには特別なパラメータを追加すれば十分であるが、もちろんこのパラメータは重複送信を防止するためのものであり、リクエストマークの決定はそれ以外には何の影響も与えない。もちろん、このリクエスト マークを実装する別の方法を考えることもできます。つまり、このような需要はほとんど出てこないのです。