當(dāng)前位置:首頁(yè)>WordPress建站>WordPress開(kāi)發(fā)>WordPress Ajax 端點(diǎn)實(shí)現(xiàn)的 3 個(gè)變體

WordPress Ajax 端點(diǎn)實(shí)現(xiàn)的 3 個(gè)變體

至少有三種方法可以在 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é) 翻譯整理。

推薦閱讀:

聲明:本站所有文章,如無(wú)特殊說(shuō)明或標(biāo)注,均為本站原創(chuàng)發(fā)布。任何個(gè)人或組織,在未征得本站同意時(shí),禁止復(fù)制、盜用、采集、發(fā)布本站內(nèi)容到任何網(wǎng)站、書(shū)籍等各類媒體平臺(tái)。如若本站內(nèi)容侵犯了原著者的合法權(quán)益,可聯(lián)系我們進(jìn)行處理。

給TA打賞
共{{data.count}}人
人已打賞
歡迎關(guān)注WordPress大學(xué)公眾號(hào) WPDAXUE
WordPress開(kāi)發(fā)

從您的WordPress插件提供可覆蓋的模板

2021-8-30 8:11:08

WordPress開(kāi)發(fā)

如何在 WordPress 中創(chuàng)建自定義頁(yè)面模板

2021-9-19 8:08:34

2 條回復(fù) A文章作者 M管理員
  1. 我曾寫(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)自由。

  2. 縉哥哥

    不明覺(jué)厲……

?
個(gè)人中心
購(gòu)物車
優(yōu)惠劵
今日簽到
有新私信 私信列表
搜索

禄丰县| 桂平市| 灵山县| 前郭尔| 宁远县| 梅州市| 太谷县| 始兴县| 三门县| 唐河县| 天长市| 伽师县| 枣阳市| 永川市| 华亭县| 凉城县| 陆川县| 宁海县| 洛宁县| 景泰县| 上蔡县| 宜兴市| 抚州市| 白河县| 客服| 达州市| 南皮县| 池州市| 科尔| 阿瓦提县| 屯门区| 六安市| 神池县| 调兵山市| 呼玛县| 莱西市| 宜城市| 启东市| 郑州市| 于都县| 安丘市|