用于发起 WordPress REST API 请求的工具。它是 window.fetch 的封装。

安装

安装该模块

npm install @wordpress/api-fetch --save

此包假定你的代码将在 ES2015+ 环境中运行。如果你使用的环境对这些语言特性和 API 的支持有限或完全不支持,则应在代码中包含 @wordpress/babel-preset-default 随附的 polyfill。

用法

GET

import apiFetch from '@wordpress/api-fetch';

apiFetch( { path: '/wp/v2/posts' } ).then( ( posts ) => {
    console.log( posts );
} );

带查询参数的 GET

import apiFetch from '@wordpress/api-fetch';
import { addQueryArgs } from '@wordpress/url';

const queryParams = { include: [1,2,3] }; // 返回 ID 为 1,2,3 的文章。

apiFetch( { path: addQueryArgs( '/wp/v2/posts', queryParams ) } ).then( ( posts ) => {
    console.log( posts );
} );

POST

apiFetch( {
    path: '/wp/v2/posts/1',
    method: 'POST',
    data: { title: 'New Post Title' },
} ).then( ( res ) => {
    console.log( res );
} );

选项

apiFetch 支持并透传所有 fetch 全局对象 的选项。

此外,还提供以下选项:

path (string)

作为 url 的简写,追加到当前站点的 REST API 根 URL 之后。

url (string)

要获取数据的端点的绝对 URL。请求仍会通过已注册的中间件,因此在将其指向其他站点之前,请参阅对其他站点的请求。

parse (boolean, 默认 true)

与 fetch 不同,apiFetch 的 Promise 返回值将解析为 JSON 结果。通过传递 false 作为 parse 的值来禁用此行为。

data (object)

仅发送 POST 或 PUT 请求时有效。作为 body 的简写,接受一个将被序列化为 JSON 的对象值。

对其他站点的请求

apiFetch 旨在用于脚本运行的 WordPress 站点的 REST API。每当 WordPress 加载该包时,它都会注册根 URL 和 nonce 中间件,因此使用默认的 fetch 处理程序时,每个请求(包括使用完整 url 发出的请求)都会附带当前用户的 X-WP-Nonce 标头以及 cookies(credentials: 'include')。另一个源上的 WordPress 站点无法验证该 nonce,并会以 403 rest_cookie_invalid_nonce 错误拒绝请求,即使是公开端点也是如此;其他源也可能完全拒绝带有凭据的跨域请求。

请使用 window.fetch 进行对其他站点的请求,或者从服务器发起请求。浏览器对另一个站点的请求仍需该站点允许跨域请求;WordPress 站点通过其 REST API 默认发送的 CORS 标头来实现这一点。

import apiFetch from '@wordpress/api-fetch';

// 同站:经过中间件。
apiFetch( { path: '/wp/v2/posts' } ).then( ( posts ) => {
    console.log( posts );
} );

// 其他站点:直接使用 fetch。
window
    .fetch( 'https://example.com/wp-json/wp/v2/posts' )
    .then( ( response ) => response.json() )
    .then( ( posts ) => {
        console.log( posts );
    } );

中止请求

可以通过使用 AbortController 来中止请求,这与使用原生 fetch API 时的方式相同。

对于不支持 AbortController 的旧版浏览器,你可以选择:

  • 提供你自己的 AbortController polyfill,如果你仍然希望它能够被中止。
  • 忽略它,如下例所示。

示例

const controller =
    typeof AbortController === 'undefined' ? undefined : new AbortController();

apiFetch( { path: '/wp/v2/posts', signal: controller?.signal } ).catch(
    ( error ) => {
        // 如果浏览器不支持 AbortController,则下面的代码永远不会记录日志。
        // 然而,在大多数情况下这应该没问题,因为它可以被视为一种渐进式增强。
        if ( error.name === 'AbortError' ) {
            console.log( 'Request has been aborted' );
        }
    }
);

controller?.abort();

中间件

api-fetch 包支持中间件。中间件是你可用于包装 apiFetch 调用的函数,以便对 API 请求执行任何预处理/后处理操作。

示例

import apiFetch from '@wordpress/api-fetch';

apiFetch.use( ( options, next ) => {
    const start = Date.now();
    const result = next( options );
    result.then( () => {
        console.log( 'The request took ' + ( Date.now() - start ) + 'ms' );
    } );
    return result;
} );

移除中间件

apiFetch.unregister 按引用移除中间件,并返回其是否已被注册。内置中间件也可以被移除,只要它们在 apiFetch 上暴露出来即可。

import apiFetch from '@wordpress/api-fetch';

// 发送 `DELETE` 作为 `DELETE`,而不是作为携带 `X-HTTP-Method-Override` 标头的 `POST`。
apiFetch.unregister( apiFetch.httpV1Middleware );

移除是全局的。页面上的每个 apiFetch 调用都将失去该中间件,因此请只移除你自己注册的中间件,或者整个页面都可以无需其行为的内置中间件。httpV1Middleware 的存在是为了确保在拒绝 PATCH、PUT 和 DELETE 的服务器和防火墙上请求仍能正常工作;移除它可能会导致在这些站点上保存失败。

内置中间件

api-fetch 包提供了内置中间件,你可以使用它们来提供 nonce 和自定义 rootURL。

Nonce 中间件

import apiFetch from '@wordpress/api-fetch';

const nonce = 'nonce value';
apiFetch.use( apiFetch.createNonceMiddleware( nonce ) );

createNonceMiddleware 返回的函数包含一个 nonce 属性,对应于当前正在使用的 nonce。如果你有新鲜的 nonce 值要使用,也可以赋值给此属性。

根 URL 中间件

import apiFetch from '@wordpress/api-fetch';

const rootURL = 'http://my-wordpress-site/wp-json/';
apiFetch.use( apiFetch.createRootURLMiddleware( rootURL ) );

自定义 fetch 处理程序

api-fetch 包使用 window.fetch 发起请求,但你可以通过使用 setFetchHandler 方法来使用自定义 fetch 处理程序。自定义 fetch 处理程序将接收传递给 apiFetch 调用的 options。

示例

下面的示例使用自定义 fetch 处理程序,通过 axios 发起所有请求。

import apiFetch from '@wordpress/api-fetch';
import axios from 'axios';

apiFetch.setFetchHandler( ( options ) => {
    const { url, path, data, method } = options;

    return axios( {
        url: url || path,
        method,
        data,
    } );
} );

默认处理程序仍然可用,因此可以在以后恢复它。

apiFetch.setFetchHandler( apiFetch.defaultFetchHandler );

为此包做出贡献

这是 Gutenberg 项目的一部分独立包。该项目组织为一个 monorepo。它由多个自包含的软件包组成,每个包都有特定的用途。此 monorepo 中的包发布到 npm,并被 WordPress 以及其他软件项目使用。

要了解有关为此包或整个 Gutenberg 做出贡献的更多信息,请阅读项目的主要 贡献者指南。