在昨天的文章裡,筆者和大家分享 WordPress 如何透過 admin-ajax.php 以及動態鉤點的運用,瞭解如何在不重新加載整個頁面的情況下,實現從後端取得資料並更新部分網頁內容的流程。
除了 WordPress 傳統的 AJAX 機制以外,還有另一個方式可以達成前後端的資料交換,也是今天要分享的章節— WordPress REST API。
REST(Representational State Transfer, 表現狀態轉移)形式的 API 提供了一種具有靈活性的方法,便於開發者處理和應用程式相資料關聯的物件 (object) 和集合 (collection)。它是一種軟體設計的概念,不是一種硬性的規範,使用這種概念來設計的 API 也稱為 RESTful API。
以 WordPress REST API 為例,每一個端點都與 WordPress 中的特定資料類型(例如:文章、頁面、分類等)相關聯。開發者能夠透過 HTTP 協定,利用這些端點來傳送和接收JSON 格式的資料,從而在 WordPress 網站上執行內容的新增、修改、查詢、刪除等各種操作。
REST 風格的 API 使用 JSON 格式傳遞、接收資料,主要是由於JSON的資料結構既簡單又輕量,不僅便於人們閱讀,也方便機器解析。而且 JSON 在各種程式語言受到廣泛的支援及應用,無論是 Web 還是行動裝置上的 App,都可以透過 JSON 格式的資料交換,開發和 WordPress 互動的應用程式。
圖:AJAX 流程
使用 admin_ajax.php
作為 AJAX 的資料入口的定義方式和 WordPress 定義 REST 的方式有很大的區別。前者利用傳數的參數 action
和 wp_ajax_
及 wp_ajax_nopriv_
兩組字串,結合成動態鉤點,以執行註冊在該鉤點中的程式。
圖:REST 流程
後者則透過 register_rest_route
函式定義端點、處理的回呼函式,並註冊到 rest_api_init
鉤點。當 WordPress 接收到網址為該定義的端點時,則執行回呼函式,函式處理後回應 JSON 格式的資料。
當然,設計好的 REST API 也可以作為 AJAX 使用,不過相較於傳統使用 admin_ajax.php
作為 AJAX 的資料入口的作法,還是有很大的區別。
以下為 WordPress 內建的 REST 端點,可以點擊資源名稱上的連結查看官方文件。
資源名稱 | 端點 | 說明 |
---|---|---|
Posts | /wp/v2/posts | 管理網站上的文章,包括查詢、新增、刪除和更新文章。 |
Post Revisions | /wp/v2/posts/<id> /revisions |
提供文章的修訂版本的存取能力,允許開發者檢索過去的文章版本。 |
Categories | /wp/v2/categories | 管理文章的分類,包括新增、刪除和更新分類。 |
Tags | /wp/v2/tags | 管理和查詢文章的標籤,允許加上新標籤並讀取、更新或刪除現有的標籤。 |
Pages | /wp/v2/pages | 處理網站的靜態頁面,包括新增、更新、刪除和查詢頁面。 |
Page Revisions | /wp/v2/pages/<id> /revisions |
用於查詢和管理頁面的修訂版本、查看過去的頁面版本。 |
Comments | /wp/v2/comments | 查詢和管理文章和頁面的評論,包括發布新評論和修改或刪除現有迴響。 |
Taxonomies | /wp/v2/taxonomies | 提供對文章的分類法的存取和管理,包括查詢已定義的分類法詳情。 |
Media | /wp/v2/media | 管理和查詢媒體項目,例如圖片和影片,包括上傳新媒體和查詢、更新或刪除現有媒體。 |
Users | /wp/v2/users | 管理和查詢用戶資訊,包括新增新用戶、查詢、更新或刪除現有用戶。 |
Post Types | /wp/v2/types | 提供對網站上定義的文章類型的存取,允許開發者查詢有關這些類型的詳細資訊。 |
Post Statuses | /wp/v2/statuses | 允許開發者查詢和管理文章的可能狀態(例如草稿 或已發布 )。 |
Settings | /wp/v2/settings | 提供對網站設定的管理和存取,允許讀取和更新網站的核心設定。 |
Themes | /wp/v2/themes | 查詢和更改當前啟用的佈景主題的資訊,也可以查詢可用主題的列表。 |
Search | /wp/v2/search | 允許通過 REST API 搜尋網站內容,提供與現有 WordPress 搜尋功能相似的功能。 |
Block Types | /wp/v2/block-types | 提供有關註冊區塊類型的資訊的存取,這些區塊類型可用於編輯文章和頁面。 |
Blocks | /wp/v2/blocks | 管理和查詢可重用的塊,這些區塊可以在多個文章和頁面之間共享。 |
Block Revisions | /wp/v2/blocks/<id> /autosaves/ |
允許開發者查詢和管理可重用區塊的修訂版本,提供對過去的區塊版本的存取。 |
Block Renderer | /wp/v2/block-renderer | 渲染區塊的內容,讓開發者能以程式化的方式查詢區塊的 HTML 輸出。 |
Block Directory Items | /wp/v2/block-directory/search | 允許搜尋可用的區塊目錄項目,為使用者提供一個界面來搜尋和安裝新的區塊。 |
Plugins | /wp/v2/plugins | 提供對安裝的外掛的管理和存取,允許開發者查詢有關已安裝外掛的資訊,以及啟用或停用它們。 |
藉由這些已經內建的 REST API,我們甚至可以直接拿來打造一個 SPA (Single-page application, 單頁式應用程式)式的網頁,或者其它技術來打造全新的網站,例如使用 Next.js 搭配 React,而完全不用 PHP 當作前台,僅僅使用 WordPress 當作後台及資料管理之用,酷吧!
圖:Postman 上的 WordPress API 集合
關於內建的 REST API,我們大可不必一個一個 API 上官方網站去查詢文件,在 Postman 有熱心的開發者建立了 WordPress 的 API 集合,例如:這裡,我們可以直接 fork 到我們的 Postman 帳號上,接著設定好相關的環境變數,將 URL 變數設成自己的開發環境,就可以開始把玩每一支 API 了。
在下一個段落介紹如何設計 REST API,測試的工作也交給 Postman,有系統性地進行開發。
比起前一篇文章的 AJAX 方法簡潔許多。使用到一個鉤點和一個 WordPress 函式。
圖:示範用的程式片段 Gist
第 6 至 10 行:處理該 REST 端點進來的資料用的函式。
第 18 至 29 行:註冊 API 的端點路由。
第 22 行:命名空間。
第 25 行:HTTP 請求的類型。
第 26 行:回呼函式的名稱。
第 31 行:註冊到 rest_api_init 鉤點。
圖:Postman 測試結果
開啟 Postman 打看看,該 REST API 是否接通。
當有些功能必須限制權限時,該怎麼做?
在 register_rest_route 函式的第三個參數是一個選項陣列。在該陣列中的 permission_callback
欄位可以定義一個權限控制的回呼函式,如下:
圖:示範用的程式片段
第 15 至 17 行:定義一個回呼函式,回傳值為布林值,來判斷這次的請求要允許還是拒決。
圖:Postman 測試結果
依照 REST 風格的 API 設計概念來說,API 都應該是無狀態的 (stateless)。簡單的說,就是 API 的資料傳入和輸出都不應該會被其它狀態影響,例如 Cookie。
正確的作法是採用 Oauth 或 JWT 認證,這樣做的話才能達到不管是 Web 也好, 行動裝置上的 App 也好,在存取 API 的行為是一致的。
雖說如此,或許是為了降低 WordPress REST 的使用技術門檻,仍支援傳統的 session cookie 的方式取得登入的使用者資料。只要在發起請求的 header 資訊中加上 X-WP-Nonce
欄位,或者請求主題的欄位中有 _wpnonce
欄位。
傳給 REST API 所需的 nonce 來自以下方法:
wp_create_nonce( 'wp_rest' ); // 只能是 wp_rest
有兩種方法可以取得夠過上述函式產生的 REST 專用 nonce。
動圖:Postman 測試傳入 nonce
當 WordPress 的 REST API 有取得 nonce 進行驗證,和使用者相關的函式才會正常運作,這些函式包括但不限於:
如果想要全平台都可以共用同一個 API 的話,建議可以避免使用 Cookie 驗證,改用其它驗證機制。
今天寫了落落長,最後總結一下 WordPress 中的兩種資料交換機制:傳統的 AJAX 方法以及 WordPress REST API。前者藉由 admin-ajax.php 和動態鉤點,而後者則提供一個較為直覺且結構化的方法。
雖然傳統的 AJAX 方法有其便利之處,但從長遠的角度和跨平台的可用性來看,REST API 提供了更多的靈活性和擴展性唷。
參考官方文件:
課後思考:
筆者曾看過為了繞過 WordPress 的 nonce 機制,而在自己的 REST API 設計上初始化時,直接取用核心取得 Cookie 並登入的那一段邏輯來用。這樣的作法,你覺得這樣做有什麼優點?有什麼缺點?
前篇解答參考:
網站上常見的往下滑動自動換頁生成下一頁的內容、網站即時聊天、互動式投票等等。都是一些常見的使用 AJAX 的網站功能例子,透過這些應用,提供更流暢的用戶體驗。
大大你好:
我使用POSTMAN代入_wpnonce會出現403,需要做其他設定嗎?
{
"code": "rest_cookie_invalid_nonce",
"message": "Cookie 檢查失敗",
"data": {
"status": 403
}
}
使用twenty-twenty-one新增按鈕,使用JS發送ajax則會成功。
http://localhost/wordpress/wp-json/ironman/v1/say_hi
確認 _wpnonce 接收的值是由 wp_create_nonce( 'wp_rest' );
產生的,不能用我的範例的值,再試試。
似乎是使用POSTMAN發請求而網站不知道登入者是誰,後來依此網站教學,設定Cookie有成功了。
https://dev.to/david_woolf/using-postman-with-the-wordpress-rest-api-41bk