为fetch添加拦截器功能

fetch 添加拦截器拦截器

使用过axios的便会知道axios 有axios.interceptors.request.use请求拦截器与service.interceptors.response.use响应拦截器,可以请求前和,then,catch前统一处理响应信息或者response

expand_fetch.js

const req_interceptors = []   //请求拦截方法存放
const res_interceptors = []	//响应拦截方法存放

 
function  expand_fetch( url, option = { } ){ 
	if( !option.method ){
		option.method = 'GET'    
	 }
	
	//多个请求拦截器依次更改option 
	req_interceptors.forEach( fn => option = fn(option) )
	
	return  new Promise((resolve,reject)=>{

					//使用原生fetch
					fetch(url,option).then(( res )=>{‘
					
						//多个响应拦截器依次更改res 
						res_interceptors.forEach( fn => res = fn(res) )
						
						resolve(res)
					})
					.catch((error)=>{
						reject(error)
					})
			})
}

//挂载添加和删除拦截器的方法
expand_fetch.interceptors = {
		request:{ use : (fn)=>{
						req_interceptors.push(fn)
						return fn
						},
					eject:(data)=>{
						if(req_interceptors.indexOf(data) !== -1){
							req_interceptors.splice(req_interceptors.indexOf(data),1)
						}
					}

		},
		response:{ use : (fn)=>{
							res_interceptors.push(fn)
							return fn
						}},
						eject:(data)=>{
						if(res_interceptors.indexOf(data) !== -1){
							res_interceptors.splice(res_interceptors.indexOf(data),1)
						}
					}
}

export default expand_fetch

使用

import Fetch from './expand_fetch.js'

//为post数据转为 json 发送
const c_req = Fetch.interceptors.request.use((option)=>{
		if(option.method === "POST"){
				option.body = JSON.stringify(option.body)
		}

		return option
})

//直接获取到返回内容的数据
const c_res = Fetch.interceptors.response.use((res)=>{
		if(res.code === 200 && res.data ){
			return res.data
		}
		return res
})

//清除拦截器
Fetch.interceptors.request.eject(c_req)
Fetch.interceptors.response.eject(c_res)


  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
下面是一个使用Typescript对fetch进行封装,并添加拦截器的例子: ```typescript interface ApiOptions { method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'OPTIONS'; headers?: HeadersInit; body?: BodyInit; credentials?: RequestCredentials; mode?: RequestMode; cache?: RequestCache; } interface ApiResponse<T = any> { code: number; message: string; data: T; } interface Interceptor { request?: (options: ApiOptions) => ApiOptions | Promise<ApiOptions>; response?: <T>(response: ApiResponse<T>) => ApiResponse<T> | Promise<ApiResponse<T>>; } class FetchApi { private baseUrl: string; private interceptors: Interceptor; constructor(baseUrl: string, interceptors?: Interceptor) { this.baseUrl = baseUrl; this.interceptors = interceptors || {}; } public async get<T = any>(url: string, options?: ApiOptions): Promise<ApiResponse<T>> { return await this.request<T>(url, { ...options, method: 'GET' }); } public async post<T = any>(url: string, options?: ApiOptions): Promise<ApiResponse<T>> { return await this.request<T>(url, { ...options, method: 'POST' }); } public async put<T = any>(url: string, options?: ApiOptions): Promise<ApiResponse<T>> { return await this.request<T>(url, { ...options, method: 'PUT' }); } public async delete<T = any>(url: string, options?: ApiOptions): Promise<ApiResponse<T>> { return await this.request<T>(url, { ...options, method: 'DELETE' }); } private async request<T>(url: string, options: ApiOptions): Promise<ApiResponse<T>> { const requestOptions = await this.interceptRequest(options); const requestUrl = this.baseUrl + url; const response = await fetch(requestUrl, requestOptions); const responseData = await response.json(); const apiResponse = { code: response.status, message: responseData.message, data: responseData.data }; return await this.interceptResponse(apiResponse); } private async interceptRequest(options: ApiOptions): Promise<ApiOptions> { if (this.interceptors.request) { const interceptedOptions = await this.interceptors.request(options); return interceptedOptions || options; } return options; } private async interceptResponse<T>(response: ApiResponse<T>): Promise<ApiResponse<T>> { if (this.interceptors.response) { const interceptedResponse = await this.interceptors.response(response); return interceptedResponse || response; } return response; } } ``` 在这个例子中,我们创建了一个FetchApi类,它具有get、post、put、delete四个方法,用于发送对应的请求。在构造函数中,我们传入了baseUrl和interceptors两个参数,interceptors表示拦截器对象,它包含request和response两个方法,用于在请求和响应过程中进行拦截。 在get、post、put、delete四个方法中,我们调用了request方法,并传入了对应的请求方法。request方法内部首先调用interceptRequest方法,用于拦截请求。然后使用fetch函数发送请求,并解析响应体。最后调用interceptResponse方法,用于拦截响应,并解析响应体。 在interceptRequest和interceptResponse方法中,我们判断了拦截器对象是否存在,并分别调用了request和response方法,用于进行拦截。如果拦截器对象未定义对应的方法,则直接返回原始参数。 使用方法如下: ```typescript const api = new FetchApi('https://example.com', { request: (options) => { options.headers = { 'Authorization': 'Bearer token' }; return options; }, response: (response) => { if (response.code === 401) { // 处理未授权的情况 } return response; } }); api.get('/user').then(response => { console.log(response.data); }).catch(error => { console.error(error); }); ``` 在这个例子中,我们首先创建了一个FetchApi对象,传入了baseUrl和interceptors参数。在interceptors参数中,我们定义了request和response方法,用于在请求和响应过程中进行拦截。 然后我们使用get方法发送了一个请求,并在then方法中处理响应。如果发生错误,我们则在catch方法中进行处理。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值