Ajax/阅读更多:多个check_ajax_referer()和wp_create_nonce()不能独立工作

时间:2018-12-13 作者:user2115227

我在同一页上有多个wp\\U查询。每个查询的底部都有一个AJAX“阅读更多”按钮。我发现的问题是,我一次只能让一个人工作。函数中首先添加的函数。php,其中一个有效-另一个在管理ajax时出现403错误。php。

我对AJAX非常陌生,所以我可能已经对它进行了彻底的哈希处理,我相信有一种方法可以将其组合到单个函数中(首选!)但如果我能找到一种让他们都独立工作的方法,那就好了。

这是我的代码:

自定义页面中的2个WP\\U查询可以正常工作。php模板:

第一个:

<?php
    //Find out how many posts 
    $total_posts = wp_count_posts(\'smart_maps\');
    $total_posts = $total_posts->publish;
    $number_shown = 0;


     $the_query = new WP_Query( $args ); ?>
    <?php if ( $the_query->have_posts() ) : ?>
    <div id="smartmaps" class="smartmaps col xs-col-14 xs-offset-1 md-col-12 md-offset-2" style="display:none;">
        <div class="in-here-smartmaps">
            <?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
            <a href="<?php echo get_permalink(get_the_ID());?>">
                <div class="single-smartmap col xs-col-16 md-col-8">
                    <div class="col xs-col-8 xs-offset-4 md-col-4 md-offset-0 center">
                        <div class="image-element">
                            <img src="<?php the_field(\'thumbnail_image\');?>" class="circle">
                            <div class="image-overlay circle"></div>
                        </div>
                    </div>
                    <div class="col xs-col-14 xs-offset-1 md-col-10 md-offset-1">
                        <h5 class="smart-map-title"><?php the_title();?></h5>
                        <?php if(get_field(\'icons\')) :?>
                            <div class="block-icons">
                                <?php if(in_array(\'Heart\', get_field(\'icons\'))) :?>
                                    <span class="icon-heart"></span>
                                <?php endif;?>
                                <?php if(in_array(\'Plant\', get_field(\'icons\'))) :?>
                                    <span class="icon-plant"></span>
                                <?php endif; ?>
                                <?php if(in_array(\'Cup\', get_field(\'icons\'))) :?>
                                    <span class="icon-cup"></span>
                                <?php endif;?>
                                <?php if(in_array(\'Book\', get_field(\'icons\'))) :?>
                                    <span class="icon-book"></span>
                                <?php endif;?>
                            </div>
                        <?php endif;?>
                    </div>
                </div>
            </a>
                <?php $number_shown++; 
            endwhile; ?>
        <?php endif;?>
        </div>
    <?php if($number_shown != $total_posts) :?>
        <div class="loadmore smarties col xs-col-14 xs-offset-1 md-col-8 md-offset-4 center">
            <h3><a href="#">LOAD MORE</a></h3>
        </div>
    <?php endif;?>

    </div>
<div clas="clearfix"></div>
第二个1:

<div id="strategic-events" class="strategicevents col xs-col-14 xs-offset-1 md-col-12 md-offset-2" style="display:none;">
    <div class="in-here-strats">
    <?php
    //Find out how many posts 
    $total_posts = wp_count_posts(\'strategic_events\');
    $total_posts = $total_posts->publish;
    $number_shown = 0;

    $args = array( \'post_type\' => \'strategic_events\', \'posts_per_page\' => 10, \'offset\' => $the_offset );


     $the_query2 = new WP_Query( $args ); ?>
    <?php if ( $the_query2->have_posts() ) : 
        while ( $the_query2->have_posts() ) : $the_query2->the_post(); ?>
        <a href="<?php echo get_permalink(get_the_ID());?>">    
            <div class="single-strategicevent col xs-col-16 md-col-8">
                <div class="col xs-col-8 xs-offset-4 md-col-4 md-offset-0 center">
                    <div class="image-element">
                        <img src="<?php the_field(\'strategic_event_image\');?>" class="circle">
                        <div class="image-overlay circle"></div>
                    </div>
                </div>
                <div class="col xs-col-14 xs-offset-1 md-col-10 md-offset-1">
                    <h5 class="strategic-event-title"><?php the_title();?></h5>
                    <?php if(get_field(\'subtitle\')) :?>
                        <p><?php the_field(\'subtitle\');?></p>   
                        <small><?php the_field(\'location_text\');?></small>          
                    <?php endif;?>
                </div>
            </div>
        </a>
            <?php $number_shown++; 
        endwhile; 
    endif; ?>
    </div>
    <?php if($number_shown != $total_posts) :?>
        <div class="loadmore strats col xs-col-14 xs-offset-1 md-col-8 md-offset-4 center">
            <h3><a href="#">LOAD MORE</a></h3>
        </div>
    <?php endif;?>

</div>
<div class="clearfix"></div>
我的JS代码(目前也在page-work.php中)。。。

<script>
var ajaxurl = "<?php echo admin_url( \'admin-ajax.php\' ); ?>";
var page = 2;
jQuery(function($) {
    $(\'body\').on(\'click\', \'.loadmore.strats\', function(e) {
        e.preventDefault();
        var data = {
            \'action\': \'load_posts_by_ajax\',
            \'page\': page,
            \'security\': \'<?php echo wp_create_nonce("load_strats_posts"); ?>\',
            \'max_page\': \'<?php global $wp_query; echo $wp_query->max_num_pages;?>\'
        };

        $.post(ajaxurl, data, function(response) {
            $(\'.in-here-strats\').append(response);
            page++;
        });
    });
});

<script>
var ajaxurl = "<?php echo admin_url( \'admin-ajax.php\' ); ?>";
var page = 2;
jQuery(function($) {
    $(\'body\').on(\'click\', \'.loadmore.smarties\', function(e) {
        e.preventDefault();
        var data = {
            \'action\': \'load_posts_by_ajax\',
            \'page\': page,
            \'security2\': \'<?php echo wp_create_nonce("load_smartmaps_posts"); ?>\',
            \'max_page\': \'<?php global $wp_query; echo $wp_query->max_num_pages;?>\'
        };

        $.post(ajaxurl, data, function(response) {
            $(\'.in-here-smartmaps\').append(response);
            page++;
        });
    });
});
</script>
还有我函数中的AJAX函数。php:

//Load More Smart Maps 
add_action(\'wp_ajax_load_posts_by_ajax\', \'load_smart_maps_by_ajax_callback\');
add_action(\'wp_ajax_nopriv_load_posts_by_ajax\', \'load_smart_maps_by_ajax_callback\');
function load_smart_maps_by_ajax_callback() {
check_ajax_referer(\'load_smartmaps_posts\', \'security2\');
$paged = $_POST[\'page\'];
$args = array(
    \'post_type\' => \'smart_maps\',
    \'post_status\' => \'publish\',
    \'posts_per_page\' => \'10\',
    \'paged\' => $paged,
);
$my_posts = new WP_Query( $args );
if ( $my_posts->have_posts() ) :
    ?>
    <?php 
        $total_posts = wp_count_posts(\'smart_maps\');
        $total_posts = $total_posts->publish;
        $number_shown = $paged * 10 - 10;?>
    <?php while ( $my_posts->have_posts() ) : $my_posts->the_post() ?>

            <a href="<?php echo get_permalink(get_the_ID());?>">
                <div class="single-smartmap col xs-col-16 md-col-8">
                    <div class="col xs-col-8 xs-offset-4 md-col-4 md-offset-0 center">
                        <div class="image-element">
                            <img src="<?php the_field(\'thumbnail_image\');?>" class="circle">
                            <div class="image-overlay circle"></div>
                        </div>
                    </div>
                    <div class="col xs-col-14 xs-offset-1 md-col-10 md-offset-1">
                        <h5 class="smart-map-title"><?php the_title();?></h5>
                        <?php if(get_field(\'icons\')) :?>
                            <div class="block-icons">
                                <?php if(in_array(\'Heart\', get_field(\'icons\'))) :?>
                                    <span class="icon-heart"></span>
                                <?php endif;?>
                                <?php if(in_array(\'Plant\', get_field(\'icons\'))) :?>
                                    <span class="icon-plant"></span>
                                <?php endif; ?>
                                <?php if(in_array(\'Cup\', get_field(\'icons\'))) :?>
                                    <span class="icon-cup"></span>
                                <?php endif;?>
                                <?php if(in_array(\'Book\', get_field(\'icons\'))) :?>
                                    <span class="icon-book"></span>
                                <?php endif;?>
                            </div>
                        <?php endif;?>
                    </div>
                </div>
            </a>
            <?php $number_shown++;
                if ( $number_shown == $total_posts ) {
                    echo \'<style>.loadmore.smarties {display:none;}</style>\';
                }
            endwhile ?>
    <?php endif;

wp_die();
}


//Load More Strategic Events
add_action(\'wp_ajax_load_posts_by_ajax\', \'load_strats_by_ajax_callback\');
add_action(\'wp_ajax_nopriv_load_posts_by_ajax\', \'load_strats_by_ajax_callback\');
function load_strats_by_ajax_callback() {
check_ajax_referer(\'load_strats_posts\', \'security\');
$paged = $_POST[\'page\'];
$args = array(
    \'post_type\' => \'strategic_events\',
    \'post_status\' => \'publish\',
    \'posts_per_page\' => \'10\',
    \'paged\' => $paged,
);
$my_posts = new WP_Query( $args );
if ( $my_posts->have_posts() ) :
    ?>
    <?php 
        $total_posts = wp_count_posts(\'strategic_events\');
        $total_posts = $total_posts->publish;
        $number_shown = $paged * 10 - 10;?>
    <?php while ( $my_posts->have_posts() ) : $my_posts->the_post() ?>

            <a href="<?php echo get_permalink(get_the_ID());?>">    
            <div class="single-strategicevent col xs-col-16 md-col-8">
                <div class="col xs-col-8 xs-offset-4 md-col-4 md-offset-0 center">
                    <div class="image-element">
                        <img src="<?php the_field(\'strategic_event_image\');?>" class="circle">
                        <div class="image-overlay circle"></div>
                    </div>
                </div>
                <div class="col xs-col-14 xs-offset-1 md-col-10 md-offset-1">
                    <h5 class="strategic-event-title"><?php the_title();?></h5>
                    <?php if(get_field(\'subtitle\')) :?>
                        <p><?php the_field(\'subtitle\');?></p>   
                        <small><?php the_field(\'location_text\');?></small>          
                    <?php endif;?>
                </div>
            </div>
        </a>
            <?php $number_shown++; 
                if ( $number_shown == $total_posts ) {
                    echo \'<style>.loadmore.strats {display:none;}</style>\';
                }
            endwhile ?>
    <?php endif;

wp_die();
}
如果可能的话,我会把它简化为一个函数,如果不可能,至少会让它独立工作。我猜它只查看了1个wp\\u nonce,并对照两个AJAX调用进行了检查,所以它读取的第一个很好,第二个是403?

2 个回复
最合适的回答,由SO网友:Sally CJ 整理而成

我发现的问题是,我一次只能让一个人工作。函数中首先添加的函数。php,其中一个有效-另一个在管理ajax时出现403错误。php。

是的,因为您的两个PHP函数(或AJAX回调)都连接到相同的AJAX操作,即load_posts_by_ajax:

// #1 AJAX action = load_posts_by_ajax
add_action(\'wp_ajax_load_posts_by_ajax\', \'load_smart_maps_by_ajax_callback\');
add_action(\'wp_ajax_nopriv_load_posts_by_ajax\', \'load_smart_maps_by_ajax_callback\');

// #2 AJAX action = load_posts_by_ajax
add_action(\'wp_ajax_load_posts_by_ajax\', \'load_strats_by_ajax_callback\');
add_action(\'wp_ajax_nopriv_load_posts_by_ajax\', \'load_strats_by_ajax_callback\');
以及check_ajax_referer() 默认情况下,退出带有403 (“禁止”)状态,例如未指定nonce或已过期:

// #1 $_REQUEST[\'security2\'] will be checked for the load_smartmaps_posts nonce action.
check_ajax_referer(\'load_smartmaps_posts\', \'security2\');

// #2 $_REQUEST[\'security\'] will be checked for the load_strats_posts nonce action.
check_ajax_referer(\'load_strats_posts\', \'security\');
您可以同时发送两个nonce(尽管没有人会这样做),也可以使用相同的nonce和$_REQUEST 键(例如。security), 但你仍然会得到意想不到的结果/响应。

因此,如果您想要“单一功能”,可以使用辅助“操作”:

PHP部件输入functions.php:

// #1 Load More Smart Maps
// No add_action( \'wp_ajax_...\' ) calls here.
function load_smart_maps_by_ajax_callback() {
    // No need to call check_ajax_referer()
    ...your code here...
}


// #2 Load More Strategic Events
// No add_action( \'wp_ajax_...\' ) calls here.
function load_strats_by_ajax_callback() {
    // No need to call check_ajax_referer()
    ...your code here...
}

add_action( \'wp_ajax_load_posts_by_ajax\', \'load_posts_by_ajax\' );
add_action( \'wp_ajax_nopriv_load_posts_by_ajax\', \'load_posts_by_ajax\' );
function load_posts_by_ajax() {
    check_ajax_referer( \'load_posts_by_ajax\', \'security\' );

    switch ( filter_input( INPUT_POST, \'action2\' ) ) {
        case \'load_smartmaps_posts\':
            load_smart_maps_by_ajax_callback();
            break;

        case \'load_strats_posts\':
            load_strats_by_ajax_callback();
            break;
    }

    wp_die();
}
  • JS部分&mdash;这个data 对象:

    // #1 On click of `.loadmore.smarties`
    var data = {
        \'action\': \'load_posts_by_ajax\',
        \'action2\': \'load_smartmaps_posts\',
        \'security\': \'<?php echo wp_create_nonce( "load_posts_by_ajax" ); ?>\', // same nonce
        ...other properties...
    };
    
    // #2 On click of `.loadmore.strats`
    var data = {
        \'action\': \'load_posts_by_ajax\',
        \'action2\': \'load_strats_posts\',
        \'security\': \'<?php echo wp_create_nonce( "load_posts_by_ajax" ); ?>\', // same nonce
        ...other properties...
    };
    
  • 但是为什么不将回调挂接到它们自己的特定AJAX操作:

    // #1 AJAX action = load_smart_maps_posts_by_ajax
    add_action(\'wp_ajax_load_smart_maps_posts_by_ajax\', \'load_smart_maps_by_ajax_callback\');
    add_action(\'wp_ajax_nopriv_load_smart_maps_posts_by_ajax\', \'load_smart_maps_by_ajax_callback\');
    
    // #2 AJAX action = load_strats_posts_by_ajax
    add_action(\'wp_ajax_load_strats_posts_by_ajax\', \'load_strats_by_ajax_callback\');
    add_action(\'wp_ajax_nopriv_load_strats_posts_by_ajax\', \'load_strats_by_ajax_callback\');
    

    SO网友:Elkrat

    WP-ajax有点奇怪。您可以将脚本排队,使其显示在页面上。您还可以本地化脚本,以便将变量粘贴到脚本所需的页面中,例如nonce、ajax地址,甚至其他您可能会发现有用的奇怪的东西。

    按如下方式注册和本地化脚本:

        wp_enqueue_script( \'name_of_function\', get_stylesheet_directory_uri() . \'/js/my_special_script.js\', array( \'jquery\' ), \'1.0\', true );
        wp_localize_script( \'name_of_function\',
                           \'name_the_script_will_see\',
                           array(
                               \'ajax_url\' => admin_url(\'admin-ajax.php\'),
                               \'ajax_nonce\' => wp_create_nonce(\'your_nonce\'),
                           ));
    
    然后必须添加两次ajax操作,一次用于公共页面,另一次用于管理页面。

    add_action(\'wp_ajax_this_is_the_ajax_name\', \'function_name_in_php\' );
    add_action(\'wp_ajax_nopriv_this_is_the_ajax_name\', \'function_name_in_php\' );
    
    然后在脚本中选择如下值:

    var data = {
                    \'action\': \'this_is_the_ajax_name\',
                    \'post_nonce\': name_the_script_will_see.ajax_nonce,
                    \'other_value_needed\': value_generated_by_script,
                };
    $.post( name_the_script_will_see.ajax_url, data, function( response_data ) { 
    
                if ( response_data.success ) {
                    alert ("Success");
                } else {
                    alert ("Error");
                }
    
    您的php脚本将以post数据的形式获取数据:

    function function_name_in_php(){
         $nonce = $_POST[\'post_nonce\'];
         $other_data = $_POST[\'other_value_needed\'];
         if ( ! wp_verify_nonce( $nonce, \'your_nonce\' ) ) {
        wp_send_json_error(array(
            \'message\'=>\'Security Token Failure\',
        )); // sends json_encoded success=false
    }
    
    我将在许多不同的脚本中使用一个nonce。我真正要做的就是确保我的请求者实际上来自我的网站。没有必要为此生成17个不同的nonce。通常我将nonce作为数据属性粘贴到提交按钮中,然后从该按钮而不是从wordpress本地化方案中提取nonce。当一个页面上有许多脚本并且它们正在访问一些相同的后端功能时,这会更加方便。

    var postData = {};
     var nonce = $(\'#register_button\').attr(\'data-nonce\');
     postData.nonce = nonce;
     postData.action = \'this_is_the_ajax_name\';
    $.post( name_the_script_will_see.ajax_url, postData, function( response_data ) { 
    
            if ( response_data.success ) {
                alert ("success");
            } else {
                alert ("Error");
            }
    
    希望这有帮助!

    相关推荐

    如何修复wp-login.php在迁移后出现错误500?

    我已经将一个word press站点迁移到一个自托管linux服务器。我的首页和所有其他页面都加载了,但是图像仍然指向我的旧服务器。我的wp登录。php页面还提供了一个错误500。我已经使用mysql终端将数据库中的siteurl和home更改为我的新数据库。我还将PHP ini文件更改为512M如果我更改“wp\\u posts”表中的guid,我可以获得要显示的图像。编辑:enabling debug showed the following: Deprecated: Methods