管理面板 API:Fetch 客户端
页面摘要: 在 React 组件内使用
useFetchClient,在其他位置使用getFetchClient,即可在调用 Strapi API 时自动附带用户的身份验证令牌。两者都暴露get、post、put和del方法,并在收到 401 响应时自动刷新令牌。
Strapi 为管理面板提供了一个内置的 HTTP 客户端,可自动管理身份验证。插件开发者应当使用它,而不是原始的 fetch 或 axios。
useFetchClient 和 getFetchClient 都从 @strapi/strapi/admin 导出,并暴露相同的 get、post、put 和 del 方法。请根据调用的发起位置进行选择:
| 入口点 | 使用场景 |
|---|---|
useFetchClient | 在 React 组件内部(在组件卸载时自动取消请求) |
getFetchClient | 服务、工具函数、事件处理函数,或任何非 React 代码 |
在深入阅读本页概念之前,请确保你已经:
- 创建了一个 Strapi 插件,
- 阅读并理解了 Admin Panel API 的基础知识。
获取数据 {#fetching-data}
最常见的操作是使用 get 获取数据。导入客户端,解构出所需的方法,然后 await 其结果:
在 React 组件内部 {#inside-a-react-component}
useFetchClient 是一个 React hook,会自动提供一个与组件生命周期绑定的 AbortSignal,因此在组件卸载时请求会被取消:
JavaScript
import { useFetchClient } from '@strapi/strapi/admin';
const MyComponent = () => {
const { get } = useFetchClient();
const fetchData = async () => {
const { data } = await get('/my-plugin/my-endpoint');
// data contains the parsed JSON response
};
};
TypeScript
import { useFetchClient } from '@strapi/strapi/admin';
const MyComponent = () => {
const { get } = useFetchClient();
const fetchData = async () => {
const { data } = await get('/my-plugin/my-endpoint');
// data contains the parsed JSON response
};
};
在 React 组件外部 {#outside-a-react-component}
getFetchClient 可在任何 JavaScript 上下文中工作。典型的模式是将调用封装在导出的辅助函数内,供插件其余部分导入使用:
JavaScript
import { getFetchClient } from '@strapi/strapi/admin';
const { get, del } = getFetchClient();
export const fetchItems = async () => {
const { data } = await get('/my-plugin/items');
return data;
};
export const deleteItem = async (id) => {
await del(`/my-plugin/items/${id}`);
};
TypeScript
import { getFetchClient } from '@strapi/strapi/admin';
const { get, del } = getFetchClient();
export const fetchItems = async () => {
const { data } = await get('/my-plugin/items');
return data;
};
export const deleteItem = async (id: string) => {
await del(`/my-plugin/items/${id}`);
};
del 方法之所以这样命名,是因为 delete 是 JavaScript 中的保留字。
使用 post 和 put 发送数据 {#sending-data}
post 和 put 方法接受负载(payload)作为第二个参数:
JavaScript
import { getFetchClient } from '@strapi/strapi/admin';
const { post, put } = getFetchClient();
// Create a new item
export const createItem = async (payload) => {
const { data } = await post('/my-plugin/items', payload);
return data;
};
// Update an existing item
export const updateItem = async (id, payload) => {
const { data } = await put(`/my-plugin/items/${id}`, payload);
return data;
};
TypeScript
import { getFetchClient } from '@strapi/strapi/admin';
const { post, put } = getFetchClient();
// Create a new item
export const createItem = async (payload: Record<string, unknown>) => {
const { data } = await post('/my-plugin/items', payload);
return data;
};
// Update an existing item
export const updateItem = async (id: string, payload: Record<string, unknown>) => {
const { data } = await put(`/my-plugin/items/${id}`, payload);
return data;
};
当发送 FormData(例如文件上传)时,fetch 客户端会自动移除 Content-Type 请求头,以便浏览器设置正确的 multipart 边界。
配置请求 {#options}
所有方法都接受一个 options 对象作为最后一个参数:
| Option | Type | Description |
|---|---|---|
params | object | 查询字符串参数。自动序列化。 |
headers | Record<string, string> | 额外的请求头。会与默认值合并。 |
signal | AbortSignal | 用于取消请求。useFetchClient 会自动提供一个。 |
validateStatus | (status: number) => boolean \| null | 用于决定哪些 HTTP 状态码应抛出错误的自定义函数。 |
responseType | 'json' \| 'blob' \| 'text' \| 'arrayBuffer' | 控制响应解析方式(见 Response types)。仅在 get 上有效。 |
查询参数 {#params}
传入 params 即可自动序列化查询字符串:
const { data } = await get('/content-manager/collection-types/api::article.article', {
params: {
page: 1,
pageSize: 10,
sort: 'title:asc',
},
});
响应类型 {#response-types}
默认情况下,响应会被解析为 JSON。get 方法接受 responseType 选项来处理非 JSON 响应,例如文件下载、CSV 导出或二进制数据:
responseType value | Response parsed as |
|---|---|
json | JSON 对象(默认) |
blob | Blob |
text | 纯文本字符串 |
arrayBuffer | ArrayBuffer |
非 JSON 响应会在返回对象中包含 status 和 headers:
JavaScript
import { useFetchClient } from '@strapi/strapi/admin';
const DownloadButton = () => {
const { get } = useFetchClient();
const downloadFile = async (url) => {
const { data: blob, status, headers } = await get(url, { responseType: 'blob' });
// Process the blob, for example to trigger a file download
};
};
TypeScript
import { useFetchClient } from '@strapi/strapi/admin';
const DownloadButton = () => {
const { get } = useFetchClient();
const downloadFile = async (url: string) => {
const { data: blob, status, headers } = await get(url, { responseType: 'blob' });
// Process the blob, for example to trigger a file download
};
};
错误处理 {#error-handling}
当请求失败时,fetch 客户端会抛出 FetchError。使用 isFetchError 工具函数可以安全地检查错误:
JavaScript
import { useFetchClient, isFetchError } from '@strapi/strapi/admin';
const MyComponent = () => {
const { get } = useFetchClient();
const fetchData = async () => {
try {
const { data } = await get('/my-plugin/my-endpoint');
// handle success
} catch (error) {
if (isFetchError(error)) {
// error.status contains the HTTP status code
console.error('Request failed:', error.status, error.message);
} else {
throw error; // re-throw non-fetch errors
}
}
};
};
TypeScript
import { useFetchClient, isFetchError } from '@strapi/strapi/admin';
const MyComponent = () => {
const { get } = useFetchClient();
const fetchData = async () => {
try {
const { data } = await get('/my-plugin/my-endpoint');
// handle success
} catch (error) {
if (isFetchError(error)) {
// error.status contains the HTTP status code
console.error('Request failed:', error.status, error.message);
} else {
throw error; // re-throw non-fetch errors
}
}
};
};
当请求返回 401 状态码时,fetch 客户端会自动刷新身份验证令牌并重试请求,然后才会抛出错误。此自动重试不适用于身份验证端点本身。
👉 关于服务器端错误处理(控制器、服务、中间件),请参阅 Error handling。