至少有三種方法可以在 WordPress 插件或主題中實(shí)現(xiàn) Ajax 端點(diǎn)。Admin-Ajax 是永遠(yuǎn)存在的東西,而 WP_REST 是“新”的方式,重寫(xiě)規(guī)則則是另一種方法。我將用代碼示例解釋所有三種變體,并嘗試找出優(yōu)缺點(diǎn)。

Admin-Ajax
自 WordPress 2.1.0 版起,admin-ajax.php文件位于 wp-admin 目錄中。它的名字暗示管理員只能使用,但它可以用于未經(jīng)身份驗(yàn)證和身份驗(yàn)證的請(qǐng)求。
對(duì)該文件的請(qǐng)求將啟動(dòng) WordPress 核心、主題(和子主題)functions.php 和插件,但不會(huì)以全局 WP_Query 執(zhí)行或模板解析結(jié)束。只要$_REQUEST['action']提供了值,它就可以用于任何類型的請(qǐng)求方法(GET、POST、PUT、PATCH、DELETE)。此操作值用于觸發(fā)操作。如果沒(méi)有注冊(cè)動(dòng)作處理程序,則返回一個(gè)字符串0。
基本的未經(jīng)身份驗(yàn)證的 Admin-Ajax 示例
<?php
namespace PublicFunctionOrg\WordPress\CodeSamples;
// ------------------------------------------------
// /wp-admin/admin-ajax.php?action=my_action
// ------------------------------------------------
function my_unauthorized_action_handler(){
$latestPostTitles = array_map(function($post){
return $post->post_title;
}, get_posts());
wp_send_json($latestPostTitles);
exit;
}
add_action('wp_ajax_nopriv_my_action',__NAMESPACE__.'\my_unauthorized_action_handler');
// 大多數(shù)情況下,您希望授權(quán)用戶也能夠使用公共端點(diǎn)
add_action('wp_ajax_my_action',__NAMESPACE__.'\my_unauthorized_action_handler');
通過(guò)這幾行代碼,我們可以使用 URL 調(diào)用我們?nèi)碌?Ajax 端點(diǎn)/wp-admin/admin-ajax.php?action=my_action。請(qǐng)務(wù)必注意,該wp_ajax_noproiv_{action}操作僅在您的請(qǐng)求未通過(guò)身份驗(yàn)證時(shí)才有效。如果您在瀏覽器中有一個(gè)正在運(yùn)行的登錄會(huì)話,則響應(yīng)將為0. 因此,在大多數(shù)情況下,您還應(yīng)該添加經(jīng)過(guò)身份驗(yàn)證的操作。
基本經(jīng)過(guò)身份驗(yàn)證的 Admin-Ajax 示例
如果要提供僅限經(jīng)過(guò)身份驗(yàn)證的用戶使用的數(shù)據(jù),則需要注冊(cè)一個(gè)wp_ajax_{action}操作處理程序。未經(jīng)身份驗(yàn)證的請(qǐng)求會(huì)收到一個(gè)0字符串響應(yīng)。
<?php
namespace PublicFunctionOrg\WordPress\CodeSamples;
// ------------------------------------------------
// /wp-admin/admin-ajax.php?action=my_action
// ------------------------------------------------
function my_authorized_action_handler(){
wp_send_json([
"firstname" => wp_get_current_user()->first_name,
"lastname" => wp_get_current_user()->last_name,
]);
exit;
}
add_action('wp_ajax_my_action',__NAMESPACE__.'\my_authorized_action_handler');
Admin-Ajax 方法實(shí)現(xiàn)起來(lái)非常簡(jiǎn)單,但不適合構(gòu)建大型 api。
WP_REST
WP_REST 1.0 隨 WordPress 4.4 版一起提供。當(dāng) Gutenberg 與 WordPress 5.0 一起發(fā)布時(shí),后端的事情變得更加異步。需要一種更結(jié)構(gòu)化的方式來(lái)實(shí)現(xiàn) Ajax 調(diào)用,所以升級(jí)到了 WP_REST 2.0。
基本未經(jīng)身份驗(yàn)證的 WP_REST 示例
使用該rest_api_init操作來(lái)注冊(cè)您自己的 api 端點(diǎn)。您可以使用該register_rest_route功能注冊(cè)新路線。
<?php
namespace PublicFunctionOrg\WordPress\CodeSamples;
// ------------------------------------------------
// GET /wp-json/code-samples/v1/basic
// ------------------------------------------------
add_action( 'rest_api_init', function () {
register_rest_route(
"code-samples/v1",
"/basic",
[
'methods' => \WP_REST_Server::READABLE,
'permission_callback' => '__return_true',
'callback' => function (\WP_REST_Request $request) {
return array_map( function ( $post ) {
return $post->post_title;
}, get_posts() );
},
]
);
} );
我們現(xiàn)在可以使用 URL 調(diào)用我們的 Ajax 路由/wp-json/code-samples/v1/basic。
第一個(gè)參數(shù)是命名空間,它通常由插件的 slug 或描述內(nèi)容的慢字符串和版本字符串組成。第二個(gè)參數(shù)是這個(gè)命名空間內(nèi)的路由。
第三個(gè)參數(shù)是一個(gè)配置數(shù)組。該methods參數(shù)允許您選擇此路由將接受的請(qǐng)求方法。通常,每個(gè)路由只允許一個(gè)方法,但您也可以指定多個(gè)方法作為逗號(hào)分隔的列表或方法數(shù)組。有效方法字符串的常量可以在 WP_REST_Server 類中找到。如果沒(méi)有明確指定方法,則使用GET。
您還必須定義一個(gè)permission_callback. 由于我們的路由接受任何 GET 請(qǐng)求,我們可以使用一個(gè)名為的核心函數(shù)__return_true,該函數(shù)通過(guò)始終返回 true 來(lái)授予繼續(xù)處理所有請(qǐng)求的權(quán)限。
最后但并非最不重要的callback論點(diǎn)。它需要一些可調(diào)用的值來(lái)返回響應(yīng)數(shù)據(jù)。響應(yīng)格式為 JSON。
基本經(jīng)過(guò)身份驗(yàn)證的 WP_REST 示例
除了permission_callback參數(shù)之外,它與未經(jīng)身份驗(yàn)證的代碼示例幾乎相同。
<?php
namespace PublicFunctionOrg\WordPress\CodeSamples;
// ------------------------------------------------
// GET /wp-json/code-samples/v1/basic
// ------------------------------------------------
add_action( 'rest_api_init', function () {
register_rest_route(
"code-samples/v1",
"/basic",
[
'methods' => \WP_REST_Server::READABLE,
'permission_callback' => function (\WP_REST_Request $request) {
return is_user_logged_in();
},
'callback' => function (\WP_REST_Request $request) {
return [
"firstname" => wp_get_current_user()->first_name,
"lastname" => wp_get_current_user()->last_name,
];
},
]
);
} );
此端點(diǎn)僅接受授權(quán)請(qǐng)求,因?yàn)槲覀兪褂迷?code>is_user_logged_in()函數(shù)檢查登錄狀態(tài)。但是,如果您在瀏覽器中具有有效的登錄會(huì)話并調(diào)用此 url,您將收到未經(jīng)授權(quán)的錯(cuò)誤響應(yīng)。這是因?yàn)?WP_REST api 使用 nonce 令牌進(jìn)行授權(quán)檢查。您可以使用@wordpress/api-fetch包,如果您登錄,它會(huì)自動(dòng)處理 nonce 令牌。
Ajax 端點(diǎn)仍然相當(dāng)容易實(shí)現(xiàn),但您必須指定名稱空間、請(qǐng)求方法和權(quán)限處理,這將有助于您處理更大的項(xiàng)目。
重寫(xiě)規(guī)則
添加重寫(xiě)規(guī)則是這三種變體中最復(fù)雜的。我們需要使用兩個(gè)動(dòng)作和一個(gè)過(guò)濾器來(lái)使其工作。
<?php
namespace PublicFunctionOrg\WordPress\CodeSamples;
// ------------------------------------------------
// /my/custom/route
// ------------------------------------------------
add_filter( 'query_vars', function( $vars ) {
$vars[] = "my_route";
return $vars;
});
add_action( 'init', function(){
add_rewrite_rule( '^my/custom/route/?', 'index.php?my_route=1' );
});
add_action( 'parse_request', function(){
if ( isset( $wp->query_vars[ "my_route"] ) &&
"1" === $wp->query_vars[ "my_route"]
) {
$latestPostTitles = array_map(function($post){
return $post->post_title;
}, get_posts());
wp_send_json($latestPostTitles);
exit;
}
});
首先,我們需要添加一個(gè)查詢變量,以便我們可以識(shí)別我們的 Ajax 請(qǐng)求。其次,我們向系統(tǒng)添加自定義重寫(xiě)規(guī)則并將其映射到我們的查詢變量。在最后一步,我們攔截請(qǐng)求解析器并檢查我們的變量是否存在。如果是,我們可以假設(shè)我們的路由已被調(diào)用并提供響應(yīng)。
建議
僅在具有一兩個(gè)非常簡(jiǎn)單的端點(diǎn)的非常簡(jiǎn)單的情況下才使用 Admin-Ajax。
在我看來(lái),WP_REST 是大多數(shù)情況下的方法。它迫使您考慮為路由命名空間和處理權(quán)限,并具有更多用于驗(yàn)證和清理請(qǐng)求變量的好功能。您可以設(shè)計(jì)適當(dāng)?shù)?RESTful 實(shí)體,但也可以將其用于簡(jiǎn)單的 Ajax 路由。
僅當(dāng)您有 Admin-Ajax 或 WP_REST 無(wú)法滿足的嚴(yán)格 URL 路徑或響應(yīng)格式要求時(shí),才回退到重寫(xiě)規(guī)則變體。
注:本文出自 medium.com,作者為Edward Bock,由 WordPress大學(xué) 翻譯整理。
推薦閱讀:
- 使用這些 WordPress 插件擴(kuò)展 REST API
- 使用REST API TO MiniProgram插件快速為WordPress網(wǎng)站生成小程序
- 使用WordPress REST API創(chuàng)建WordPress設(shè)置頁(yè)面
- 禁用 WordPress 的 JSON REST API
- WordPress:自定義WP REST API (WP API)授權(quán)





我曾寫(xiě)過(guò)對(duì)WordPress兩種AJAX的方法的對(duì)比,并且有對(duì)比代碼清晰分析。實(shí)際上就是本文的方法一和方法三
https://blog.brain1981.com/2078.html
方法二即WP的自帶Rest API其實(shí)我不太喜歡用,因?yàn)槊總€(gè)網(wǎng)站都有,可能涉及安全問(wèn)題并且不如自己寫(xiě)的接口用起來(lái)自由。
不明覺(jué)厲……