Typescript Fetch拦截器实现 (Http Fetch Interceptor)

  最近用vue + typescript搭了个框架,使用Fetch做数据交互,需要处理请求和返回过程中的特殊情况,例如,授权失败,返回401状态码时,跳转登录页面。或者是token到期后重新请求授权更新token。
  为了处理上面的问题,派出Interceptor出场,查了网上不少现成的代码,基本都不是基于fetch的, 少量为fetch写的拦截器,基本都不符合心意或不能用于typescript。
  得,发扬自力更生的思想,自己动手丰衣足食。不过真正实现起来,还是蛮麻烦的,还好在github上有可以借鉴的案例。

  放上代码供参考,以下代码是基于Typescript的,如果使用javascript,可以手动修改,去掉类型声明等等就好。

export class FetchInterceptor {
    public interceptors: any[] = [];
    public interceptor(fetch: (input: RequestInfo, init?: RequestInit | undefined) => Promise,
        options: { input: RequestInfo, init?: RequestInit | undefined }) {
        const reversedInterceptors = this.interceptors.reduce((array, interceptor) => [...[interceptor], array]);
        let promise = Promise.resolve(options);
        reversedInterceptors.forEach(({ request, requestError }: any) => {
            if (request || requestError) {
                promise = promise.then(opt => request(opt.input, opt.init), requestError);
            }
        });
        let responsePromise = promise.then(opt => fetch(opt.input, opt.init));
        reversedInterceptors.forEach(({ response, responseError }: any) => {
            if (response || responseError) {
                responsePromise = responsePromise.then((resp: Response) => {
                    return response(resp);
                });
            }
        });
        return responsePromise;
    }
}

window.fetch = ((fetch) => {
    return (input: RequestInfo, init?: RequestInit | undefined) => {
        return fetchInterceptor.interceptor(fetch, { input, init });
    };
})(window.fetch);

export const fetchInterceptor = new FetchInterceptor();

使用方法:

fetchInterceptor.interceptors.push({
  request: (input: string, init: RequestInit) => {
    const token = store.getters.getToken;
    let headers = new Headers(init.headers);
    headers.append('Authorization', 'Bearer ' + token);
    init.headers = headers;
    return { input, init };
  }
}, {
    response: (response: Response) => {
      if (response.status === 401) {
        router.replace('signin');
      }
      return response;
    }
  });

你可能感兴趣的:(Typescript Fetch拦截器实现 (Http Fetch Interceptor))