简单谈一下wordpress中的ajax请求,为什么会一直返回“0”



最近写插件的时候遇到一个问题,使用ajax向wordpress发起请求,返回回来的始终是0!

先简单说下wordpress的ajax请求。

发起请求

wordpress中要发起ajax请求不难,分别需要如下:

PHP记录一个ajax钩子,以便后续操作:

function press_data()
{
    // do it...
    exit;
}

wp_register_script('request_data', plugins_url('request_data.js', __FILE__), array('jquery'));
wp_enqueue_script('request_data');

add_action('wp_ajax_press_data', 'press_data');

从上面可以得出以下结论:

    wordpress是通过add_action记录一个ajax请求的钩子
    钩子的名称前缀必须是“wp_ajax_”
    钩子回调方法中必须通过“exit”或“die”来结束输出(后面会继续说明)
    通过“wp_register_script”注册一个js,用于发起请求

js发起ajax请求:

jQuery.ajax({
    type: 'POST',
    url: ajaxurl,
    data: {
        action: 'press_data'
    },
    success: function(res) {
        // get res
    }
});

从上面可以得出以下结论:

    url请求地址为一个固定的变量:ajaxurl
    请求的“data”数据中必须有一个“action”属性,属性值必须和之前ajax记录请求的钩子名称对应

这些并不难,如果说还要增加点花样的话,比如说php传个值让ajax请求时带上,那么可以通过函数:wp_localize_script,如下:

// 注册一个钩子
wp_register_script('request_data', plugins_url('request_data.js', __FILE__), array('jquery'));

// 传递一个值
wp_localize_script('request_data', 'request_data', array(
    'url' => 'http://levi.cg.am'
));

// 调用这个js
wp_enqueue_script('request_data');


而之前的js也仅需要这么修改即可:

jQuery.ajax({
    type: 'POST',
    url: ajaxurl,
    data: {
        action: 'press_data',
        form: request_data.url
    },
    success: function(res) {
        // get res
    }
});


Ajax的流程

要搞清楚为什么ajax请求一直返回0这个问题,先要搞清楚整个请求流程。

wordpress注册ajax的流程:

    后台load必要的文件、钩子、函数
    接受add_action请求,根据请求记录所有的钩子,包含ajax钩子
    等待触发

wordpress触发ajax请求

    wordpress接受ajax的地址为/wp-admin/admin-ajax.php
    请求文件前先load必要的文件、钩子、函数(和注册时一样)
    检查action请求,若找不到输出0,结束
    检查并触发系统对应的钩子、ajax请求
    检查action请求并根据用户登录与否进行触发
        登录用户触发钩子:wp_ajax_{action_name}
        未登录用户触发钩子:wp_ajax_nopriv_{action_name}
    最终输出0,结束请求

看到这里我想大家应该明白为什么ajax钩子的回调函数中都要以“exit”或“die”来结束输出了吧,如果你不结束输出的话,最终都会返回一个“0”来结束本次请求结果;这样可能会破坏你原有的数据结构。

什么情况下ajax请求返回都是“0”

在网上搜了下,国内也有人遇到过这个情况,但是他们给出的答案大同小异都是类似“位置不对”,“需要放在最后”;其实这样的答案并不能说正确,可能没有弄明白整个流程顺序
没有action请求

js发起ajax请求时候没有action,或者action并不在“data”属性中,例如:

没有action请求

js发起ajax请求时候没有action,或者action并不在“data”属性中,例如:

// 错误示范
jQuery.ajax(
    action: 'action_name',
    data: {}
);

// 正确示范
jQuery.ajax({
    data: { action: 'action_name' }
});

钩子名称不正确

PHP记录钩子的名称不对应,比如说请求名称为“action_name”,那么对应的钩子名称就是“wp_ajax_action_name”
钩子没有被记录

在加载钩子前已经返回或终止了程序,这个是我这次本身的问题,我写的plugin中有这么一段代码


if ( ! defined( 'WP_LOAD_IMPORTERS' ) )
 return;
add_action('wp_ajax_stop_import', array($import, 'stop'));



如果你是正常浏览导入页面没有问题,但是如果是从ajax过来的请求呢?他没有定义常量“WP_LOAD_IMPORTERS”哦,那么他会被return掉,而不执行当前plugin中的后续代码,那显然也不会触发对应的ajax请求的钩子;同理,exit也是一样的;
为了证明我的想法是否正确,我做了以下测试
if (!isset($_GET['test']))
{
 echo 'you can't';
 exit;
}
if ( ! defined( 'WP_LOAD_IMPORTERS' ) )
 return;
// some....
页面中URL加“&test”正常浏览,ajax请求流程第2步会加载文件、钩子、函数,当加载到这个文件的时候会因为没有text这个请求,而被终止执行


钩子没有被触发

举个例子,我的ajax请求钩子注册在数据导入的钩子中,而我当前并不在数据导入页面,那么显然也是不会触发的。
function cnblog2wp_lv_importer_init()
{
    add_action('wp_ajax_stop_import', array($import, 'stop'));
}

add_action('admin_init', 'cnblog2wp_lv_importer_init', 15);
钩子触发不正确

前面有提到,注册用户触发的钩子是“wp_ajax_{action_name}”,非注册的用户触发的钩子是:“wp_ajax_nopriv_{action_name}”;如果说你的ajax中cookies不一致,那么很有可能触发的钩子不正确哦;另外还有譬如“跨域”等情况,这个已超出这篇文章讨论范围了,暂且先不深究,如果说你的功能是一样的,你也不妨可以注册两个钩子与之对应的钩子哦。
如何检测ajax请求

以前专门写过一篇文章,详细可以查看这里:

http://levi.cg.am/archives/2324

这里我列举两个简单的方式来分辨ajax请求:

// 将特定字符作为请求参数作为判断
$is_ajax = isset($_GET['is_ajax']);

// 通过url来判断
strpos($_SERVER['REQUEST_URI'], 'wp-admin/admin-ajax.php') !== false

wordpress中几个怪异的问题

如果说wordpress的ajax请求返回0,这个不算怪异,那么下面这几个应该相当诡异了,我们暂且可以看做是wordpress设计上的缺陷。
慎用exit

先说一个和主题相关的问题,上面说了ajax请求时必须通过exit、die结束请求。但是请谨慎使用exit或die来终止PHP的进程。如果你有使用“wp_enqueue_script”给模板添加js、css,那么exit很有可能将会阻止输出指定的js、css。

那在使用exit的情况下,怎么才能正确输出指定js或css?你可以在模板中,直接输出静态资源请求的HTML,例如:



printf(
    '<script type="text/javascript" src="%s?ver=wordpress"></script>',
    plugins_url('mod.js', dirname(__FILE__))
);
后台模板记得开头先写“wrap”。

<!-- 正确状态 -->
<div class="wrap">
</div>

<!-- 不正确状态 -->
<style>
/* ... */
<style>
<div class="wrap">
</div>

如果你有在后台通过钩子“admin_notices”,输出提示信息。

    正确使用状态下,提示信息是在标题的下方(wrap区域里面);
    错误使用状态下,提示信息是在标题的上方(wrap区域外面);





  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现分页Ajax无限加载功能,可以按照以下步骤进行: 1. 在WordPress主题创建一个新的页面模板,命名为“ajax-pagination.php”(或者其他你喜欢的名字)。 2. 在模板添加需要分页的内容。 3. 在模板添加一个按钮或链接,用于加载更多内容。 4. 使用jQuery编写Ajax代码,将按钮或链接与模板的内容连接起来。 5. 在functions.php文件添加一个新的函数,用于处理Ajax请求。 6. 编写一个新的WordPress查询,用于获取下一页的内容。 7. 将查询结果返回Ajax请求,并将其添加到页面上。 以下是一个简单的示例代码,演示如何实现分页Ajax无限加载功能: 在ajax-pagination.php文件,添加以下代码: ``` <div id="content"> <?php $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; $args = array( 'post_type' => 'post', 'posts_per_page' => 3, 'paged' => $paged ); $query = new WP_Query($args); if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post(); // 输出文章内容 endwhile; endif; ?> </div> <div id="load-more"> <a href="#">加载更多</a> </div> ``` 在JavaScript文件,添加以下代码: ``` jQuery(document).ready(function($) { $('#load-more a').click(function() { var button = $(this), data = { 'action': 'load_more', 'query': loadmore_params.posts, 'page': loadmore_params.current_page }; $.ajax({ url: loadmore_params.ajaxurl, data: data, type: 'POST', beforeSend: function(xhr) { button.text('正在加载...'); }, success: function(data) { if (data) { button.text('加载更多').prev().before(data); loadmore_params.current_page++; if (loadmore_params.current_page == loadmore_params.max_page) button.remove(); } else { button.remove(); } } }); return false; }); }); ``` 在functions.php文件,添加以下代码: ``` add_action('wp_ajax_load_more', 'load_more'); add_action('wp_ajax_nopriv_load_more', 'load_more'); function load_more() { $query = json_decode(stripslashes($_POST['query']), true); $query['paged'] = $_POST['page'] + 1; $posts = new WP_Query($query); if ($posts->have_posts()) { while ($posts->have_posts()) { $posts->the_post(); // 输出文章内容 } } die; } ``` 以上代码仅仅是一个示例,你需要根据自己的实际情况进行修改和调整。但是,这个示例可以帮助你了解如何使用WordPressAjax来实现分页Ajax无限加载功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值