uniapp中模仿axios封装请求,并实现请求拦截和响应拦截

www.jswusn.com Other 2025-04-08 16:05:03 35次浏览


rquest.js:

// 定义请求配置接口
interface RequestConfig { 
  url: string;   
  method: 'GET' | 'POST' | 'PUT' | 'DELETE';   
  data?: any; 
  header?: any; 
  timeout?: number;
}

// 请求拦截器数组
const requestInterceptors: ((config: RequestConfig) => RequestConfig | Promise<RequestConfig>)[] = [];
// 响应拦截器数组
const responseInterceptors: ((response: any) => any | Promise<any>)[] = [];
const responseErrorInterceptors: ((error: any) => any | Promise<any>)[] = [];

// 添加请求拦截器
const addRequestInterceptor = (interceptor: (config: RequestConfig) => RequestConfig | Promise<RequestConfig>) => { 
  requestInterceptors.push(interceptor);
};

// 添加响应拦截器
const addResponseInterceptor = (  
    success: (response: any) => any | Promise<any>,  
    error: (error: any) => any | Promise<any>
) => {  
  responseInterceptors.push(success); 
  responseErrorInterceptors.push(error);
};


// 封装请求方法
const request = async <T>(config: RequestConfig): Promise<T> => { 
  let newConfig = config;   
  // 执行请求拦截器   
  for (const interceptor of requestInterceptors) { 
    newConfig = await interceptor(newConfig);  
  }
      
  return new Promise((resolve, reject) => {   
    uni.request({        
      url: newConfig.url,    
      method: newConfig.method,   
      data: newConfig.data,         
      header: newConfig.header,        
      timeout: newConfig.timeout || 60000,  
      success: async (res) => {      
        let newResponse = res;     
        // 执行响应拦截器          
        for (const interceptor of responseInterceptors) {    
          newResponse = await interceptor(newResponse);       
        }        
        if (newResponse.statusCode >= 200 && newResponse.statusCode < 300) {     
          resolve(newResponse.data as T);    
        } else {               
          reject(new Error(`请求失败,状态码: ${newResponse.statusCode}`));    
        }       
      },      
      fail: async (err) => {     
        let newError = err;       
        // 执行响应错误拦截器     
        for (const interceptor of responseErrorInterceptors) {   
          newError = await interceptor(newError);     
        }              
        reject(new Error(`请求出错: ${newError.errMsg}`));  
      }      
    });  
  });
};

// 封装 get 请求
const get = async <T>(url: string, config?: Omit<RequestConfig, 'url' | 'method'>): Promise<T> => { 
  return request<T>({      
    ...config,   
    url,      
    method: 'GET'  
  });
};

// 封装 post 请求
const post = async <T>(url: string, data?: any, config?: Omit<RequestConfig, 'url' | 'method' | 'data'>): Promise<T> => {  
  return request<T>({        
    ...config,      
    url,       
    method: 'POST',  
    data  
  });
};

// 封装 put 请求
const put = async <T>(url: string, data?: any, config?: Omit<RequestConfig, 'url' | 'method' | 'data'>): Promise<T> => { 
  return request<T>({     
    ...config,   
    url,     
    method: 'PUT',    
    data  
  });
};

// 封装 delete 请求
const del = async <T>(url: string, config?: Omit<RequestConfig, 'url' | 'method'>): Promise<T> => {  
  return request<T>({      
    ...config,   
    url,     
    method: 'DELETE' 
  });
};

export { get, post, put, del, addRequestInterceptor, addResponseInterceptor };


使用示例:

<template>
  <view>
    <button @click="fetchData">获取数据</button>
    <view>{{ data }}</view>
  </view>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import { get, addRequestInterceptor, addResponseInterceptor } from './request';

const data = ref<any | null>(null);

// 添加请求拦截器示例
addRequestInterceptor((config) => {
  // 例如添加 token 到请求头
  config.header = {
    ...config.header,
    Authorization: 'Bearer your_token'
  };
  return config;
});

// 添加响应拦截器示例
addResponseInterceptor(
    (response) => {
      // 对响应数据进行处理
      console.log('响应数据处理前:', response);
      return response;
    },
    (error) => {
      // 对响应错误进行处理
      console.error('响应错误处理:', error);
      return error;
    }
);

const fetchData = async () => {
  try {
    const result = await get<any>('https://api.example.com/data');
    data.value = result;
  } catch (error) {
    console.error('请求出错:', error);
  }
};
</script>


技术分享

苏南名片

  • 联系人:吴经理
  • 电话:152-1887-1916
  • 邮箱:message@jswusn.com
  • 地址:江苏省苏州市相城区

热门文章

Copyright © 2018-2025 jswusn.com 版权所有

技术支持:苏州网站建设  苏ICP备18036849号