fetch API 拦截器
发布于 7 年前 作者 doxiaodong 10712 次浏览 来自 分享

直接上地址:https://github.com/doxiaodong/intercept-fetch

可以拦截哪些:

  • request
  • response
  • success
  • error

特点:

  • 可以设置多个拦截器,并设置先后顺序,id 越小的越先执行,但 id 必须大于等于 0
  • 所有拦截返回 Promise,所以可以在拦截中加入异步操作

--------- 下边的 copy 自 README

Usage

  • install npm i intercept-fetch --save
  • add interceptors
import {
  FetchClient,
  Interceptor
} from 'intercept-fetch'

const fetchClient = new FetchClient()
const interceptor = new Interceptor({
  cors: {
    id: 0,
    request(url, config) {
      url += '&a=1'
      config.mode = 'cors'
      return Promise.resolve([url, config])
    },
    success(data) {
      return new Promise((resolve) => {
        setTimeout(() => {
          console.log('res a', data)
          data.a = 'intercepta'
          resolve(data)
        }, 1000)
      })
    }
  },
  credentials: {
    id: 1,
    request(url, config) {
      url += '&b=2'
      config.credentials = 'include'
      return Promise.resolve([url, config])
    },
    response(response) {
      return Promise.resolve(error)
    },
    success(data) {
      return new Promise((resolve) => {
        setTimeout(() => {
          console.log('res b', data)
          data.b = 'interceptb'
          resolve(data)
        }, 1000)
      })
    },
    error(error) {
      return Promise.resolve(error)
    }
  }
})

fetchClient.setInterceptors(interceptor)

fetchClient.get('http://google.com')

Warning: at end of each interceptor, you can reject(any) to catch, if you want to complete the fetch flow, please resolve as ref example!!!

class FetchClient

  • getInterceptors(): IInterceptors
  • setInterceptors(interceptors: Interceptor): void
  • clearInterceptors(): void
  • request(url: string | Request, config?: RequestInit): Promise<any>
  • get(url: string, param?: { [key: string]: any }, config?: RequestInit): Promise<any>
fetchClient.get('http://google.com', { date: Date.now() })
  • post(url: string, config?: RequestInit): Promise<any>
  • put(url: string, config?: RequestInit): Promise<any>
  • delete(url: string, config?: RequestInit): Promise<any>
  • options(url: string, config?: RequestInit): Promise<any>
  • head(url: string, config?: RequestInit): Promise<any>
  • patch(url: string, config?: RequestInit): Promise<any>

class Interceptor

  • interface
export interface IInterceptor {
  id?: number
  request?: (url: string | Request, config: RequestInit) => Promise<[string | Request, RequestInit]>
  response?: (res: Response) => Promise<Response>
  success?: (data: any) => Promise<any>
  error?: (res: Response) => Promise<Response>
}
export interface IInterceptors {
  [key: string]: IInterceptor
}
  • set(key: string, value: IInterceptor): void
  • get(key: string): IInterceptor
  • delete(key: string): void
  • has(key: string): boolean
  • forEach(callback: (value?: IInterceptor, key?: string, target?: Interceptor) => void, thisArg?): void
  • merge(interceptors: Interceptor): Interceptor // merge this Interceptor to param Interceptor
const I = new Interceptor({
  a: {

  }
})
I.merge(new Interceptor({
  a: {
    request(url, config){
      return Promise.resolve([url, config])
    }
  }, 
  b: {}
}))

// I
// a: {
// }, 
// b: {}

Differences with https://github.com/werk85/fetch-intercept

  • All interceptors(request, response, success, error) are Promise

  • Provide a interceptor class

  • Can add more than one interceptors ordered by id, and the smaller id is call first

  • Support typescript

5 回复

应用场景是什么呢?

@zsea ,在request的时候统一加header,加cors权限之类的。 比如: https://github.com/doxiaodong/darlin-react/blob/master/src/base/fetch/interceptor.tsx 我自己的用法

拦截header或者预处理本来就可以实现啊,promise设计模式之before,after

@Qquanwei , 是的,我这个只是做一个 类似 angularjs interceptor的封装,可以快捷使用,类似的 有 https://github.com/werk85/fetch-intercept

回到顶部