最近用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<Response>,
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;
}
});
网友评论