基于fetch封装http请求
import qs from 'qs';
import Config from '../config/index';
type Method = 'GET' | 'POST' | 'HEAD' | 'OPTIONS' | 'PUT' | 'PATCH' | 'DELETE' | 'TRACE' | 'CONNECT';
export enum HttpStateCode {
ERROR = 500, // Request failed.
SUCCESS = 200, // Request successful.
UNAUTHORIZED = 403, // Request unauthorized.
INVALID_TOKEN = 401 // Request invalid token.
}
export interface RESTful<T = any> {
//* code: 服务器返回状态码
code: HttpStateCode;
//* errMsg: 服务器返回消息
errMsg: string;
//* data: 服务器返回响应体
data: T;
}
type AsyncResponseResult<T> = Promise<T>;
// defaultHeaders:设置默认响应头
const defaultHeaders = {
'Content-Type': 'application/json; charset=utf-8'
};
const request = (method: Method = 'GET') => {
return async <T>(url: string, body?: any, customHeaders = {}): AsyncResponseResult<T> => {
const headers: any = Object.assign({}, defaultHeaders, customHeaders);
const contentType = headers['Content-Type']; // 获取请求头信息
const localToken = sessionStorage.getItem('ACCESS_TOKEN');
// 如果本地存在 token,则请求头中携带 Authorization 发送过去
localToken && (headers['Authorization'] = localToken);
if (/^application\/json/.test(contentType)) {
body = JSON.stringify(body);
}
const response = await fetch(Config.apiPrefix + url, {
method,
headers,
body,
mode: 'cors',
cache: 'default'
});
if (response.ok && response.status >= 200 && response.status < 300) {
const responseType = response.headers.get('content-type') as string;
if (/^application\/json/.test(responseType)) {
return response.json(); // 处理 JSON 数据格式
} else if (/^text\//.test(responseType)) {
return response.text() as Promise<any>; // 处理文本
}
}
// 抛出异常 Expection
throw Error(response.statusText);
};
};
// 创建对应的请求方法,暴露给外部使用
const post = request('POST');
const get = request('GET');
export { post, get };
使用用例:
import { post, RESTful } from 'fetch';
interface Todo {
name: string;
done: boolean;
}
post<RESTful<Todo>>('/api/v3/findTodo').then(result => {
// result => RESTful<Todo>
})