什么是 AJAX?
AJAX 是 Asynchronous JavaScript And XML(异步 JavaScript 和 XML)的缩写。XML 是一种数据交换格式,而 UX 则是软件开发者对 User Experience(用户体验)的简称。Ajax 是一种互联网通信技术,它允许在用户浏览器中显示的网页向服务器请求特定信息,并在不重新加载整个页面的情况下将新信息显示在同一页面上。你可以想象这如何改善用户体验。
虽然 XML 是传统上使用的数据交换格式,但交换的数据实际上可以是任何方便的格式。在使用 PHP 代码时,许多开发者偏爱 JSON,因为从传输的数据流中创建的内部数据结构更容易进行接口对接。
要看到 AJAX 的实际应用,请前往您的 WordPress 管理区域并添加一个分类或标签。当您点击“Add New”(新建)按钮时,请仔细观察页面发生了变化但并未真正重新加载。还不信服?检查浏览器的历史记录,如果页面已重新加载,您将看到该页面的两个条目。
AJAX 甚至不需要用户操作即可工作。Google Docs 会自动每隔几分钟保存您的文档,而无需您手动发起保存操作。
为什么要使用 AJAX?
显然,它能改善用户体验。AJAX 允许您呈现动态、响应式且用户友好的体验,而不是展示枯燥的静态页面。用户可以立即获得反馈,知道他们采取的行动是否正确或错误。无需在发现某个字段有错误之前提交整个表单。重要字段可以在输入数据后立即进行验证。或者,当用户键入时可以提供建议。
AJAX 可以大幅减少来回流动的数据量。只需交换相关数据,而不是页面重新加载时会发生的所有页面内容。
具体与 WordPress 插件相关,AJAX 无疑是启动独立于 WordPress 内容的过程的最佳方式。如果您以前编写过 PHP 代码,您可能会通过简单地链接到一个新的 PHP 页面来完成此操作。遵循该链接的用户将启动该过程。这个问题的缺点是,当您链接到新的外部 PHP 页面时,无法访问任何 WordPress 函数。过去,开发人员通过在他们的新的 PHP 页面上包含核心文件 wp-load.php 来访问 WordPress 函数。这样做的缺点是,您再也无法知道此文件的正确路径。WordPress 架构现在足够灵活,可以将 /wp-content/ 和您的插件文件从其通常的位置移动到安装根目录的一个层级之外。您无法知道 wp-load.php 相对于您的插件文件的位置,也无法知道安装文件夹的绝对路径。
您可以知道的是发送 AJAX 请求的位置,因为它定义在一个全局 JavaScript 变量中。您的 PHP AJAX 处理脚本实际上是一个操作钩子(action hook),因此所有 WordPress 函数都自动可用,而不同于外部 PHP 文件。
如何使用 AJAX?
如果您是新使用 WordPress 但具有在其他环境中使用 AJAX 经验的开发人员,您将需要重新学习一些内容。WordPress 实现 AJAX 的方式很可能与您习惯的不同。如果一切都是新的,没关系。您将在这里学习基础知识。一旦您开发了一个基本的 AJAX 交换,在此基础上扩展并开发一个带有出色用户界面的杀手级应用就轻而易举了!
任何 WordPress 中的 AJAX 交换都有两个主要组件:客户端 JavaScript 或 jQuery 以及服务器端的 PHP。所有 AJAX 交换都遵循以下事件序列。
- 某种页面事件会触发一个 JavaScript 或 jQuery 函数。该函数从页面收集一些数据并通过 HTTP 请求将其发送到服务器。由于使用 JavaScript 处理 HTTP 请求很别扭,而且 jQuery 已经捆绑在 WordPress 中,因此我们将从这里开始只关注 jQuery 代码。虽然可以使用纯 JavaScript 进行 AJAX,但在有 jQuery 可用的情况下这样做不值得。
- 服务器接收请求并对数据执行某些操作。它可能会组装相关数据并以 HTTP 响应形式将其发送回客户端浏览器。这不是必需的,但由于保持用户了解正在发生的事情是可取的,因此很少不发送某种响应。
- 发送初始 AJAX 请求的 jQuery 函数接收服务器响应并对其执行某些操作。它可能会更新页面上的某些内容并通过某种方式向用户呈现消息。
使用 jQuery 进行 AJAX
现在我们将定义 jQuery 文章中的代码片段 中的“do stuff”部分。我们将使用 $.post() 方法,该方法接受三个参数:发送 POST 请求的 URL、要发送的数据以及处理服务器响应的回调函数。在我们这样做之前,我们需要先进行一些预先规划以腾出空间。我们在稍后在回调函数中使用以下赋值。其目的将在 回调部分 中更加明显。
var this2 = this;URL
所有 WordPress AJAX 请求都必须发送到 wp-admin/admin-ajax.php。正确的完整 URL 必须来自 PHP,jQuery 无法自行确定此值,您也不能在 jQuery 代码中硬编码 URL 并期望其他人能在其网站上使用您的插件。如果页面来自管理区域,WordPress 会将正确的 URL 设置在全局 JavaScript 变量 ajaxurl 中。对于来自公共区域的页面,您需要自己建立正确的 URL 并使用 wp_localize_script() 将其传递给 jQuery。这将在 PHP 部分 中更详细地介绍。现在只需知道,适用于前端和后端两端的 URL 可作为您将在 PHP 段中定义的全局对象的属性可用。在 jQuery 中引用方式如下:
my_ajax_obj.ajax_url数据
所有需要发送到服务器的数据都包含在数据数组中。除了您的应用程序需要的任何数据外,您还必须发送一个 action 参数。对于可能导致数据库更改的请求,您需要发送一个 nonce,以便服务器知道请求来自合法来源。我们提供给 .post() 方法的示例数据数组如下所示:
{
_ajax_nonce: my_ajax_obj.nonce, // nonce
action: "my_tag_count", // action
title: this.value // data
}每个组件在下面进行解释。
Nonce
Nonce 是“Number used ONCE”(一次性使用的数字)的混成词。它本质上是为任何表单的每个实例分配的唯一的序列号。nonce 是通过 PHP 脚本建立的,并以与 URL 相同的方式传递给 jQuery,作为全局对象中的属性。在这种情况下,它引用为 my_ajax_obj.nonce。
注意
真正的 nonce 需要在使用时每次刷新,以便下一个 AJAX 调用有一个新的、未使用的 nonce 作为验证。事实证明,WordPress 的 nonce 实现并非真正的 nonce。相同的 nonce 可以在 24 小时内使用多次,除非您注销。使用相同的种子短语生成 nonce 将始终在 12 小时后产生相同的数字,之后才会生成新数字。
如果您的应用程序需要严格的安全措施,请实施一个真正的 nonce 系统,其中服务器响应 Ajax 请求时发送一个新的、新鲜的 nonce 供脚本用于验证下一个请求。
如果将此 nonce 值键设为 _ajax_nonce 是最简单的。如果它与验证 nonce 的 PHP 代码协调一致,您可以使用不同的键,但使用默认值而不必担心协调更容易。这是声明此键值对的方式:
_ajax_nonce: my_ajax_obj.nonce操作
所有 WordPress AJAX 请求必须在数据中包含一个 action 参数。该值是一个任意字符串,用于部分构建您用来钩入 AJAX 处理代码的操作标签。将此值用作 AJAX 调用目的的非常简短的描述很有用。不出所料,此值的键是 'action'。在本例中,我们将使用 "my_tag_count" 作为我们的 action 值。此键值对的声明如下:
action: "my_tag_count"服务器执行任务所需的任何其他数据也包含在此数组中。如果需要传输大量字段,有两种常见格式可将数据字段组合成单个字符串以便更便捷地传输,即 XML 和 JSON。使用这些格式是可选的,但无论您采用何种方式,都需要与服务器端的 PHP 脚本进行协调。有关这些格式的更多信息请参阅以下回调部分。通常接收此类格式的数据比发送更为常见,但它也可以双向工作。
在我们的示例中,服务器只需要一个值,即所选图书标题的单个字符串,因此我们将使用键 'title'。在 jQuery 中,触发事件的对象始终包含在变量 this 中。因此,所选元素的值为 this.value。我们对此键值对的声明如下:
title: this.value回调
回调处理程序是在发出请求后服务器返回响应时执行的函数。同样,我们通常在这里看到一个匿名函数。该函数接收一个参数,即服务器响应。响应可以是任何内容,从“是”或“否”到巨大的 XML 数据库。JSON 格式的数据也是一种有用的数据格式。甚至不需要响应。如果没有响应,则无需指定回调。出于用户体验的考虑,让用户知道请求的结果总是个好主意,因此建议始终进行响应并提供某种指示以表明发生了某事。
在我们的示例中,我们将当前跟随单选输入框后的文本替换为服务器响应,其中包括由图书标题标记的文章数量。这是我们的匿名回调函数:
function( data ) {
this2.nextSibling.remove();
$( this2 ).after( data );
}data 包含整个服务器响应。之前我们通过行 var this2 = this;将触发 change 事件的对象(引用为 this)分配给 this2。这是因为闭包中的变量作用域仅延伸一个级别。通过在事件处理程序(最初仅包含 "/* do stuff */" 的部分)中分配 this2,我们可以在回调中使用它,而在此处 this 将超出作用域。
服务器响应可以采用任何形式。大量数据应编码为数据流以便于处理。XML 和 JSON 是两种常见的编码方案。
XML
XML 是 AJAX 的旧数据交换格式。毕竟它是 AJAX 中的‘X’。即使使用原生 PHP 函数处理起来可能很困难,它仍然是一种可行的交换格式。许多 PHP 程序员因此更喜欢 JSON 交换格式。如果您确实使用 XML,解析方法取决于所使用的浏览器。对于 Internet Explorer 请使用 Microsoft.XMLDOM ActiveX,对于其他所有浏览器请使用 DOMParser。请注意,自 5.8 版本发布以来,WordPress 已不再支持 Internet Explorer。
JSON
JSON 通常因其轻量级和易用性而受到青睐。实际上您可以使用 eval() 解析 JSON,但请勿这样做!使用 eval() 会带来重大的安全风险。相反,请使用专用解析器,它也更快速。使用解析器对象 JSON 的全局实例。有 特定函数可以方便地以 JSON 格式向您的 AJAX 调用提供响应。
其他
只要数据格式与 PHP 处理器协调一致,它可以是任何您喜欢的格式,例如逗号分隔、制表符分隔或任何适合您的结构。
客户端摘要
现在我们已经将回调添加为 $.post() 函数的最后一个参数,我们完成了示例 jQuery Ajax 脚本。所有组件组合在一起看起来如下:
jQuery(document).ready(function($) { //wrapper
$(".pref").change(function() { //event
var this2 = this; //use in callback
$.post(my_ajax_obj.ajax_url, { //POST request
_ajax_nonce: my_ajax_obj.nonce, //nonce
action: "my_tag_count", //action
title: this.value //data
}, function(data) { //callback
this2.nextSibling.remove(); //remove current title
$(this2).after(data); //insert server response
}
);
} );
} );此脚本可以输出到网页上的一个块中,也可以包含在其自己的文件中。该文件可以位于互联网上的任何位置,但大多数插件开发人员将其放在插件主文件夹的 /js/ 子文件夹中。除非您有其他理由,否则最好遵循约定。对于此示例,我们将文件名命名为 myjquery.js