1、安装与配置TypeScript
npm install -g typescript
2、创建Fetch服务
在src
文件夹中创建一个新的 FetchService.ts
文件。
export class FetchService {
async get<T>(url: string): Promise<T> {
const response = await fetch(url);
if (!response.ok) {
throw new Error(response.statusText);
}
const data: T = await response.json();
return data;
}
async post<T>(url: string, body: any): Promise<T> {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
if (!response.ok) {
throw new Error(response.statusText);
}
const data: T = await response.json();
return data;
}
async put<T>(url: string, body: any): Promise<T> {
const response = await fetch(url, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
if (!response.ok) {
throw new Error(response.statusText);
}
const data: T = await response.json();
return data;
}
async delete<T>(url: string): Promise<T> {
const response = await fetch(url, {
method: 'DELETE'
});
if (!response.ok) {
throw new Error(response.statusText);
}
const data: T = await response.json();
return data;
}
}
这样我们就成功地创建了一个FetchService
类,它封装了 fetch
API的 GET
, POST
, PUT
和 DELETE
方法。每个方法都返回一个Promise,该Promise解析为一个泛型 T
,这意味着你可以指定返回数据的类型。
3、使用FetchService类
import { FetchService } from './FetchService';
const fetchService = new FetchService();
// GET request
const fetchData = async () => {
try {
const data = await fetchService.get<{ message: string }>('https://api.example.com/data');
console.log(data.message);
} catch (error) {
console.error('An error occurred:', error);
}
}
// POST request
const sendData = async () => {
try {
const data = await fetchService.post<{ message: string }>('https://api.example.com/data', {
key: 'value'
});
console.log(data.message);
} catch (error) {
console.error('An error occurred:', error);
}
}
// PUT request
const updateData = async () => {
try {
const data = await fetchService.put<{ message: string }>('https://api.example.com/data', {
key: 'new-value'
});
console.log(data.message);
} catch (error) {
console.error('An error occurred:', error);
}
}
// DELETE request
const deleteData = async () => {
try {
const data = await fetchService.delete<{ message: string }>('https://api.example.com/data');
console.log(data.message);
} catch (error) {
console.error('An error occurred:', error);
}
}
fetchData();
sendData();
updateData();
deleteData();
4、拦截器实现
在这个版本的 FetchService 中,我们把公共的请求逻辑放到了 _request 方法中。我们把方法(GET、POST、PUT、DELETE),URL和可能的请求体传递给 _request 方法,然后它处理所有的共享逻辑,包括运行拦截器,发送请求,处理响应和解析JSON。
export class FetchService {
private requestInterceptors: Array<(url: string, options: RequestInit) => void> = [];
private responseInterceptors: Array<(response: Response) => void> = [];
async get<T>(url: string): Promise<T> {
return this._request('GET', url);
}
async post<T>(url: string, body: any): Promise<T> {
return this._request('POST', url, body);
}
async put<T>(url: string, body: any): Promise<T> {
return this._request('PUT', url, body);
}
async delete<T>(url: string): Promise<T> {
return this._request('DELETE', url);
}
addRequestInterceptor(interceptor: (url: string, options: RequestInit) => void) {
this.requestInterceptors.push(interceptor);
}
addResponseInterceptor(interceptor: (response: Response) => void) {
this.responseInterceptors.push(interceptor);
}
private async _request<T>(method: string, url: string, body?: any): Promise<T> {
let options: RequestInit = {
method: method,
headers: {
'Content-Type': 'application/json'
}
};
if (body) {
options.body = JSON.stringify(body);
}
this.runRequestInterceptors(url, options);
const response = await fetch(url, options);
this.runResponseInterceptors(response);
if (!response.ok) {
throw new Error(response.statusText);
}
const data: T = await response.json();
return data;
}
private runRequestInterceptors(url: string, options: RequestInit) {
this.requestInterceptors.forEach(interceptor => interceptor(url, options));
}
private runResponseInterceptors(response: Response) {
this.responseInterceptors.forEach(interceptor => interceptor(response));
}
}
使用实例:
const fetchService = new FetchService();
// 添加一个请求拦截器
fetchService.addRequestInterceptor((url, options) => {
options.headers = {
...options.headers,
'Authorization': 'Bearer ' + localStorage.getItem('token')
};
});
// 添加一个响应拦截器
fetchService.addResponseInterceptor(response => {
if (response.status === 401) {
console.error('Unauthorized!');
}
});