8

私はこのようなインターセプターを持っています

axios.interceptors.response.use(undefined, err=> {
    const error = err.response;
    console.log(error);
    if (error.status===401 && error.config && !error.config.__isRetryRequest) {
        return axios.post(Config.oauthUrl + '/token', 'grant_type=refresh_token&refresh_token='+refreshToken,
            { headers: {
          'Authorization': 'Basic ' + btoa(Config.clientId + ':' + Config.clientSecret),
          'Content-Type': 'application/x-www-form-urlencoded,charset=UTF-8'
         }
       })
        .then(response => {
          saveTokens(response.data)
          error.config.__isRetryRequest = true;
          return axios(error.config)
        })
      } 
  })

すべてが機能していますが、私の場合、1 つの React コンポーネントで 4 つの API 呼び出しがあり、このエラーが発生した場合、同じコードが 4 回実行されます。つまり、4 回更新トークンを送信して認証トークンを取得し、明らかに一度だけ実行したい

4

2 に答える 2

13

次のようなもので認証リクエストをキューに入れることができると思います:

let authTokenRequest;

// This function makes a call to get the auth token
// or it returns the same promise as an in-progress call to get the auth token
function getAuthToken() {
  if (!authTokenRequest) {
    authTokenRequest = makeActualAuthenticationRequest();
    authTokenRequest.then(resetAuthTokenRequest, resetAuthTokenRequest);
  }

  return authTokenRequest;
}

function resetAuthTokenRequest() {
  authTokenRequest = null;
}

そして、あなたのインターセプターで...

axios.interceptors.response.use(undefined, err => {
  const error = err.response;
  if (error.status===401 && error.config && !error.config.__isRetryRequest) {
    return getAuthToken().then(response => {
      saveTokens(response.data);
      error.config.__isRetryRequest = true;
      return axios(error.config);
   });
  } 
});

これがお役に立てば幸いです;)

于 2016-09-16T08:41:09.200 に答える
2

リクエストのスロットル/デバウンス ラッパーを検討しましたか? lodash には両方が組み込まれています。この 2 つの良い例を次に示します。アンダースコアではありますが、同じ違いです。

http://jsfiddle.net/missinglink/19e2r2we/

...多分あなたの場合はこのようなものですか?

axios.interceptors.response.use(undefined, err=> {
    const error = err.response;
    console.log(error);
    if (error.status===401 && error.config && !error.config.__isRetryRequest) {
        return _.debounce(axios.post(Config.oauthUrl + '/token', 'grant_type=refresh_token&refresh_token='+refreshToken,
            { headers: {
          'Authorization': 'Basic ' + btoa(Config.clientId + ':' + Config.clientSecret),
          'Content-Type': 'application/x-www-form-urlencoded,charset=UTF-8'
         }
       })
        .then(response => {
          saveTokens(response.data)
          error.config.__isRetryRequest = true;
          return axios(error.config)
        }), 1000)
      } 
  })

このように良いかもしれませんか? axios.interceptors.response.use(undefined, _.debounce(

于 2016-09-15T12:31:19.290 に答える