欢迎,来自IP地址为:195.2.71.197 的朋友


AJAX可以说是非常的酷,因为该技术可以让网站在不刷新页面的情况下加载各种元素。AJAX虽然不是重大特色功能,但却可以让我们做很多事情。

Ajax在2005年Google在搜索建议功能中被使用后变得流行起来,搜索建议功能是用户搜索框输入内容时根据用户类型提供不同的搜索建议。这不仅可以提升用户使用体验,并且完全依赖于AJAX技术。

本文将向你展示在WordPress中使用AJAX的方法,这可能比你平常用的方法复杂一些,但是采用这种方法有充分的理由。如果你比较了解HTML、CSS和PHP,并且对于Javascript有初步的认识,那么对于理解本文内容就足够了,好了,现在让我们开始。

AJAX工作原理

Ajax实际上就是Javascript,它是异步式Javascript和XML的缩写。它得以快速变得复杂的原因在于它演变成为一种网站和服务器之间的桥梁,这意味着需要联合使用Javascript、HTML和CSS代码,甚至需要使用PHP代码。

Ajax的核心是XMLHttpRequest对象,通过该对象与服务器交换数据。整个工作过程的工作原理与提交表单类似,基本步骤如下:

  1. 指定要发送的信息
  2. 配置Ajax的调用
  3. 使用XMLHttpRequest对象向服务器发送数据
  4. 服务器返回响应,通过JS代码处理响应内容

Ajax通常使用jQuery的函数功能包,如果你想不通过jQuery来使用Ajax,那么我建议可以看看W3Schools的相应教程,本文将全部使用jQuery函数。

第一个Ajax调用

在我们开始之前,需要一个可以修改主题,我们可以添加子主题或者插件。这里强烈推荐采用插件方式,因为使用起来超级简单。简而言之就是在wp-content/plugins目录下创建一个文件夹,这里将文件夹命名为ajax-test,在此文件夹中将创建一个同名的PHP文件,我使用ajax-text.php。该文件的php代码如下:

<?php 
/**
 * Plugin Name: Ajax Test
 * Plugin URI: https://www.daehub.com
 * Description: This is a plugin that allows us to test Ajax functionality in WordPress
 * Version: 1.0.0
 * Author: Daehub
 * Author URI: https://www.daehub.com
 * License: GPL2
 */

一旦保存了文件,就会在WordPress后台的插件列表中看到这个插件了。启用这个插件,便可以让自己的代码生效了。不要小看上面的代码,看似都是些注释内容,其实每个项目都是具有实际效果的,这些内容会在插件信息中显示。

将插件代码添加至WP行为队列

我们要为我们的插件添加一个JavaScript文件,并且我们将把这个文件添加至WP的行为队列中。引入队列的代码比较容易理解,内容如下:

add_action( 'wp_enqueue_scripts', 'ajax_test_enqueue_scripts' );
function ajax_test_enqueue_scripts() {
	wp_enqueue_script( 'test', plugins_url( '/test.js', __FILE__ ), array('jquery'), '1.0', true );
}

上面的代码将一个名为test.js的脚本文件加入到我们的站点中,我已经指出脚本依赖于jQuery,请确定它已经在footer中被加载。好了,现在我们通过这个脚本文件来创建一个简单的Ajax调用。

创建Ajax调用

Ajax调用有很多参数可以进行设置,可以在jQuery文档页面了解所有参数选项,我们这里只使用最基本的参数。

jQuery(document).ready( function($) {
	$.ajax({
		url: "http://yourwebsite.com",
		success: function( data ) {
			alert( 'Your home page has ' + $(data).find('div').length + ' div elements.');
		}
	})
})

以上代码所做的就是使用.ajax()函数并设置一些参数。其中“url”用于指定ajax发送请求的页面地址,而“success”表示当“url”指定的地址响应请求后所执行的处理函数。

这里的“url”参数应指向你WP网站的主页地址,如“https://www.daehub.com”或者本机调试时的“http://localhost/wordpress”,如果一切都配置正确,则会在浏览器弹出一个对话框,显示当面页面中“div”元素的数量。

这可能看起来有些丑陋,但实际上我们已经在没有重新加载页面的情况下加载了一个全新的页面,这样就实现了Ajax的基本功能。

一个完整的WordPress Ajax示例程序

WordPress做了很多工作帮助我们调用Ajax和标准化其执行过程,让我们更换“url”参数来增加更多的动态内容以更好的同服务器进行交互。下面是一个完整的例子,会将“喜爱这篇文件”功能添加到你的网站。

我把新的功能插件叫作“Post-Love”,并将所有的程序文件制作成为一个压缩文件,会在文件结尾处提供下载,方便各位朋友进行调试。

存储和显示数据

我们将在数据库存储喜欢一篇文章的数量,为了方便起见,把存储该值的功能字段叫做“post_love”,这个值将在每个单独页面的每篇文章后面显示。在插件项的php文件中加入以下代码:

add_filter( 'the_content', 'post_love_display', 99 );
function post_love_display( $content ) {
	$love_text = '';
	if ( is_single() ) {
		
		$love = get_post_meta( get_the_ID(), 'post_love', true );
		$love = ( empty( $love ) ) ? 0 : $love;
                $love_text = '<p class="love-received"><a class="love-button" href="#" data-id="' . get_the_ID() . '">give love</a><span id="love-count">' . $love . '</span></p>'; 
	}
	return $content . $love_text;
}

通过使用the_content筛选器,我们可以在文章内容下面显示我们想要得到的任何内容。这了让这个功能只在独立页面中显示,我在这里加入了is_single()条件,并且元数据中找到了文章“喜爱”的数值,并确保如果这个值为空,则显示为0。

后面的HTML代码用于页面显示,包括了一个用于指向喜欢数量链接的</span>标签。我还将文章的ID作为参数应用于连接,这个参数后面会用到。最后,我将此数值添加到文章内容后面。

这可能看来有些简单,我们可以为这个功能添加一些漂亮的样式并在WP中添加引放样式文件的动作。首先是在插件的php文件中加入引入样式表文件的动作函数:

add_action( 'wp_enqueue_scripts', 'post_love_assets' );
function post_love_assets() {
	if( is_single() ) {
		wp_enqueue_style( 'love', plugins_url( '/love.css', __FILE__ ) );
	}

注意在这里,我同样使用了is_single()判断条件,因为这个“喜欢”数值在其它页面是没有的,所以在其它类型的页面中样式表同样不会被加载。这样做的好处就是让我们的站点在加载时受我们编写的插件影响最小。在插件文件夹中添加一个love.css文件,并在此文件中加入如下的CSS内容:

.entry-content .love-button {
	background: #f14864;
	color: #fff;
	padding:11px 22px;
	display:inline-block;
	border:0px;
	text-decoration: none;
    box-shadow: 0px 6px #d2234c;
    position:relative;
}

.entry-content .love-button:hover{
	top:3px;
    box-shadow: 0px 3px #d2234c;
}

.entry-content .love-button:active{
	top:6px;
    box-shadow: none;
}

#love-count {
	background: #eee;
    box-shadow: 0px 6px #ddd;	
	color: #666;
	padding:11px 22px;
	display:inline-block;
}

最终的效果如下图所示,会在文章最后显示一个3D样式的计数器。

Ajax调用

接下来,我们编写Ajax调用函数。这涉及到JavaScript脚本的编写以及将脚本添加至WP响应队列。在这之前,我们先研究一下Ajax中“url”这个参数。在上一个例子中,我使用了绝对地址作为参数,但在实际主题或者插件应用过程中,我们不能这样设置参数,因为每个服务器都有不同的网站url。

幸运的是,WordPress帮我们想到了解决办法,它为我们提供了统一的接口文件/wp-admin/admin-ajax.php,由该文件处理全部的请求。同时,在添加Ajax处理队列时有一些小技巧,下面是完整代码:

add_action( 'wp_enqueue_scripts', 'ajax_test_enqueue_scripts' );
function ajax_test_enqueue_scripts() {
	if( is_single() ) {
		wp_enqueue_style( 'love', plugins_url( '/love.css', __FILE__ ) );
	}

	wp_enqueue_script( 'love', plugins_url( '/love.js', __FILE__ ), array('jquery'), '1.0', true );

	wp_localize_script( 'love', 'postlove', array(
		'ajax_url' => admin_url( 'admin-ajax.php' )
	));
}

正如你所看到那样,我像往常一样注册了一个JavaScript脚本,然后我使用wp_localize_script()函数给脚本传递字符串参数。这个函数最初是为JavaScript文件提供转换支持的,你可以在数组中添加任意多的字符串。在我们的脚本中,我们将postlove.ajax_url输出到admin-ajax.php文件的URL,现在我们进行相关操作。

jQuery( document ).on( 'click', '.love-button', function() {
	var post_id = jQuery(this).data('id');
	jQuery.ajax({
		url : postlove.ajax_url,
		type : 'post',
		data : {
			action : 'post_love_add_love',
			post_id : post_id
		},
		success : function( response ) {
			alert(response)
		}
	});
})

这还没有最终完成,但却可以正常同服务器通信了。首先,我们点击“give love”按钮后会执行此函数,并将此文章的ID值存存储在post_id变量中。

接下来,我们构建一个Ajax调用,URL值就使用前面讨论过的postlove.ajax_url。将类型设置为“post”同表单中设置为“post”一样。如果类型设置为“post”,可以在服务端处理函数中用$_POST得到,如果类型设置为“get”,那么就需要使用$_GET来获得数据。

“data”部分包含你想发送给自己的任何参数,我们这里需要传递文章ID来让我们知道哪一篇文章被“give love”。WordPress同样需要我们使用admin-ajax.php时发送一个请求,需要注意我们已经将它设置成为“post_love_add_love”,最后我们只需要在调用成功后提示响应。

如果你真的将响应提示出来,那么将显示为“0”,这表示一切都工作正常。如果我们没有定义相应的行为句柄(这个步骤我们将在下一步进行),admin-ajax将会对此请求响应为0,这就是为什么会显示出0的原因。

服务器侧的处理

在这个阶段,我们已经向服务器发送了据,但是我还需要告诉服务器如何处理我们的数据。我们需要在点击“喜爱”按钮后,增加功能项里的数量,并将更新后的数值反馈给客户端浏览器。为了创建一个通过Ajax传递数据的功能,我们需要两个句柄函数。

add_action( 'wp_ajax_nopriv_post_love_add_love', 'post_love_add_love' );
add_action( 'wp_ajax_post_love_add_love', 'post_love_add_love' );

function post_love_add_love() {
	
}

第一个句柄用于访客用户,第二个句柄用于登录用户。这是一个控制接入强大方式,其习惯性如下:

还记得我们如何在一个Ajax调用中定义一个行为函数么,现在只需要在前面加上wp_ajax_和wp_ajax_nopriv_前缀。函数名可任意设定,我在这里使用相同的字符串以识别相同的行为动作。现在我们创建增加数值功能函数:

add_action( 'wp_ajax_nopriv_post_love_add_love', 'post_love_add_love' );
add_action( 'wp_ajax_post_love_add_love', 'post_love_add_love' );

function post_love_add_love() {
	$love = get_post_meta( $_POST['post_id'], 'post_love', true );
	$love++;
	if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { 
		update_post_meta( $_POST['post_id'], 'post_love', $love );
		echo $love;
	}
	die();

这里没有什么特别的内容,首先得到当前喜欢的值,自增一后并保存。我们显示这个值,这个值将做为响应内容返回给浏览器。这里最需要注意的内容就是在程序最后使用die()函数,如果你不加此函数,则admin-ajax.php会使用自己的die(0)函数,并响应返回一个0值。

此时如果点击按钮,会看到相应提示,重新载入页面后,会看到相应的变化,喜欢值就会增加。现在功能上差不多了,我们可以确认在不刷新页面的情况下,喜爱值有所变化。这只是简单的JS代码,以下是完整的Ajax调用的代码,其中包含了显示计数器值的更改。

jQuery( document ).on( 'click', '.love-button', function() {
	var post_id = jQuery(this).data('id');
	jQuery.ajax({
		url : postlove.ajax_url,
		type : 'post',
		data : {
			action : 'post_love_add_love',
			post_id : post_id
		},
		success : function( response ) {
			jQuery('#love-count').html( response );
		}
	});
})

随着以上代码的完成,按相应按钮后会正确显示“喜爱”数值。现在基本上就完成了全部功能。

优雅的回退

我们的代码里a标签还没有实际意义,因为它不是实际的链接。我决定这样做的原因,因为有些人可能未启用Ajax。为什么不让这个链接生效呢,我们需要稍微修改一下代码。

首先,我们需要将目标URL设置成为同Ajax调用的urp相同:http://yourwebsite.com/wp-admin/admin-ajax.php?action=post_love_add_love&post_id=23,以下是程序的最终版本:

add_filter( 'the_content', 'post_love_display', 99 );
function post_love_display( $content ) {
 $love_text = '';
 if ( is_single() ) {
 $love = get_post_meta( get_the_ID(), 'post_love', true );
 $love = ( empty( $love ) ) ? 0 : $love;

 $love_text = '<p class="love-received"><a class="love-button" href="' . admin_url( 'admin-ajax.php?action=post_love_add_love&post_id=' . get_the_ID() ) . '" data-id="' . get_the_ID() . '">give love</a><span id="love-count">' . $love . '</span></p>'; 
 }
 return $content . $love_text;
}

由于现在我们的URL不是“#”了,我们需要在点击程序结束后返回一个false,以确保启用了JavaScript用户不会被循环调用。

jQuery( document ).on( 'click', '.love-button', function() {
	var post_id = jQuery(this).data('id');
	jQuery.ajax({
		url : postlove.ajax_url,
		type : 'post',
		data : {
			action : 'post_love_add_love',
			post_id : post_id
		},
		success : function( response ) {
			jQuery('#love-count').html( response );
		}
	});

	return false;
})

最后一步是为了区分在post_love_add_love()函数中Ajax和非Ajax的操作。当使用Ajax时,新值需要显示出来,脚本需要结束。当Ajax未启用时(例如用户重定向到admin-ajax文件),我们需要重定向回我们的文章,以下是我们post_love_add_love()函数的最终版本:

function post_love_add_love() {
	$love = get_post_meta( $_REQUEST['post_id'], 'post_love', true );
	$love++;
	update_post_meta( $_REQUEST['post_id'], 'post_love', $love );
	if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { 
		echo $love;
		die();
	}
	else {
		wp_redirect( get_permalink( $_REQUEST['post_id'] ) );
		exit();
	}
}

我们$_POST变量更换为$_REQUEST,因为Ajax用户使用post,而其它用户使用get。$_REQUEST变量无论用户采用何种方式,都可以得到数据。

更多内容

正如我前面提到的,其实Ajax使用并不困难,但是你需要知道很多简单的事情。以下是在使用Ajax过程两个最重要的方面。

安全

如果你不注意,Ajax可能会成为安全性的一个大问题。我们的按钮并不检测多重点击,于是你大可整天在那里点击它来让喜爱值增加。但是极限情况下,如果很多人同时点击时,就会增加服务器的负荷。

此外,你可能并不需要去点击那个钮,只需要访问:http://yourwebsite.com/wp-admin/admin-ajax.php?action=post_love_add_love&post_id=23页面,便可以增加计数值。

虽然我们这个小按钮对于网站的影响很小,但是如果有些插件会在前台允许删除文章的话,那么单单访问地址,就可以令插件起作用,想像一下将会发生怎样可怕的事情。

避免出现这种安全漏洞的方法就是使用随机数,随机数是一种有效的阻止表单和链接恶意尝试的方式。

用户界面和使用体验

另一个重要方面就是用户使用体验。所有技术的前提就是为了提升用户交互和减少加载时间,当你将大量工作加入到Ajax中后,你需要确认它们真的提升了用户体验。

用户需要知道发生了什么以及为什么会发生,如果我们创建了一个插件,我们首先要激活它们,如果没有激活,用户是不可能在页面上看到这个按钮的。Ajax函数的beforeSend参数允许在函数向服务器发送数据之前预先处理数据。

在此函数中,我们将在加载时预先禁用此按钮,加载成功后,我们才可以正常使用此按钮。

也可以将数值改变为某种视觉体验,在用户不知道如何操作时,可以引起用户的注意。一些小小的变化,却可以起到预料之外的效果。

同时也要注意不要走向另一个极端。随着Ajax动画技术的出现,人们似乎想把一些不必要的内容也实现动画化、动作化。只需要添加简单的动画效果,而不要让用户等动画播放结束,否则用户体验会大为下降。

结论

Ajax是开发人员提升用户交互性和降低服务器负荷强大工具,它为提升用户体验开启了无数大门,包括无刷新提交评论、无限滚动文章以及延迟加载图片等。

如果想使用好Ajax,则您需要花一些时间来仔细了解Ajax和用户界面知识,相信在熟练使用Ajax后可以令您的网站效果大大提升。

示例代码下载

One thought on “无插件WordPress网站使用AJAX与PHP示例”

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注