web-dev-qa-db-ja.com

ルート変更がvue-routerを使用する場合、すべてのAxiosリクエストを中止します

ルートを変更するときにvue-routerを使用するときに、完了する前にAxiosリクエストを中止/キャンセルするにはどうすればよいですか?.

ユーザーがページを開くとaxiosリクエストが自動的に送信されて一部のデータが取得されますが、ユーザーは応答の取得を待機していないため、vue-routerによってルートを変更しているため、多くのAxiosリクエストになります

私の問題に対する解決策はありますか

8
Ghyath Darwish

基本的には、グローバルキャンセルトークンを生成する必要があります

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

そしてそれをconfigパラメータに渡すことですべてのリクエストで使用します

GETリクエスト:

axios.get('/user/12345', {
  cancelToken: source.token
}).catch(function(thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // handle error
  }
});

POSTリクエスト:

axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token
})

次に、vue-router beforeEachナビゲーションガード内で、次のコマンドを使用してすべてのリクエストをキャンセルできます。

source.cancel('Operation canceled by the user.');

キャンセルに関する公式のaxiosガイドは次のとおりです: https://github.com/axios/axios#cancellation

8
fabruex

@fabruexからの回答は正しいです。ここに追加したいのは、多くのAPI呼び出しがある場合は、各API呼び出し構成でキャンセルトークンを渡す必要があることです。そのコードを削減するために、axiosインスタンスを作成し、その共通のキャンセルトークンを追加するリクエストインターセプターを追加し、キャンセルが行われたとき、またはルートが変更されたときにトークンに新しい値を割り当てることができます。

// Some global common cancel token source

let cancelSource = axios.CancelToken.source();

// Request interceptor

export const requestInterceptor = config => {
  config.cancelToken = cancelSource.token;
  return config;
};

// Add request interceptor like this
const request = axios.create({ baseURL: SOME_URL });
request.interceptors.request.use(requestInterceptor);


// Now you can use this axios instance like this

await request.get('/users');

// and

await request.post('/users', data);

// When you will cancel
cancelSource.cancel('Your cancellation message');

// And all the api calls initiated by axios instance which has request interceptor will be cancelled.
1
Zohaib Ijaz