使用admin-ajax.php的AJAX请求

时间:2014-03-22 15:18:07

标签: javascript php ajax wordpress extjs

我正在尝试在WordPress插件中执行AJAX请求。该请求是使用自定义短代码在文章中嵌入的首页上启动的。

我尝试合并来自the documentationthis tutorial的信息。

然而,在测试该方法时会出现问题......不会调用AJAX查询挂钩。

这是我的page.php脚本调用短代码的方式:

add_shortcode('testshortcode', 'TestShortCodeFunction');

function TestShortCodeFunction($attributes)
{
   ob_start();
   include(__DIR__.'/page.php');
   return ob_get_clean();
}

这是我的压缩测试脚本page.php

<?php

    add_action('wp_ajax_test', 'Test');
    add_action('wp_ajax_nopriv_test', 'Test');

    // do_action('wp_ajax_nopriv_test'); this calls Test()

    function Test()
    {
        echo 'Hallo';
        die();
    }
?>

<script type='text/javascript'>

    jQuery(document).ready(function() {

        console.log("JS query started");

        // The following does not call test()
        jQuery.ajax({
            type: "POST",
            url: "http://127.0.0.1/wordpress/wp-admin/admin-ajax.php?action=test",
            success: function(data) {
                console.log("Query returned: "+data);
            }
        });

    });

</script>

控制台上的输出是:

JS query started
Query returned: 0 

根据PHP调试器永远不会调用Test()函数。

admin-ajax.php根据网络监视器(URL http://127.0.0.1/wordpress/wp-admin/admin-ajax.php?action=test)执行,但返回0

根据PHP调试器调用内部admin-ajax.php do_action('wp_ajax_test')

1 个答案:

答案 0 :(得分:4)

如果你设法让这些Ajax动作挂钩在Output Buffer内工作,我会感到非常惊讶。
AFAIK,我们应该只使用PHP ob_*函数作为最后的手段。

这是一个标准实现。 JavaScript文件将在短代码回调函数中排队,在其中我们触发document.ready Ajax调用。使用admin-ajax.phpwp_localize_script URL传递给JS对象。有关详细信息,请查看代码注释;有关每个WP功能的详细信息,请查看the Codex

<?php
/**
 * Plugin Name: (SO) Simple Ajax Shortcode
 * Description: Fire an Ajax action when rendering a shortcode
 * Author:      brasofilo
 * Plugin URL:  https://stackoverflow.com/a/22585520/1287812
 */

add_shortcode( 'testshortcode', 'shortcode_so_22579460' );
add_action( 'wp_enqueue_scripts', 'enqueue_so_22579460' );
add_action( 'wp_ajax_Test_SO', 'Test_SO' );
add_action( 'wp_ajax_nopriv_Test_SO', 'Test_SO' );

/**
 * Enqueue our script inside the shortcode 
 */
function shortcode_so_22579460($attributes)
{
    wp_enqueue_script( 'my-script' );
    return '<h1>Check the broswer console.</h1>';
}

/**
 * Register and localize our script
 */
function enqueue_so_22579460() 
{
    wp_register_script( 
         'my-script',
         plugin_dir_url( __FILE__ ) . 'ajax.js',
         array( 'jquery' ) // enqueue jQuery as dependency
    );

    // We can pass any number of PHP data to the JS 'wp_ajax' object
    // Here, only the basics, Ajax URL and a security check 
    wp_localize_script( 
        'my-script', 
        'wp_ajax',
        array( 
              'ajaxurl'     => admin_url( 'admin-ajax.php' ),
              'ajaxnonce'   => wp_create_nonce( 'ajax_post_validation' ) 
         ) 
    );
}

/**
 * Ajax callback
 */
function Test_SO()
{
    // Security check
    check_ajax_referer( 'ajax_post_validation', 'security' );

    // Demonstrative boolean value to return
    $random = ( rand() % 2 != 0 );

    if( $random )
        wp_send_json_error( array( 'error' => 'Random is ODD' ) );
    else
        wp_send_json_success( 'Random is EVEN' );
}

并且JavaScript文件(ajax.js)存储在与插件文件相同的文件夹中:

jQuery(document).ready( function($) 
{
    var data = {
        action: 'Test_SO',
        security: wp_ajax.ajaxnonce
    };

    $.post( 
        wp_ajax.ajaxurl, 
        data,                   
        function( response )
        {
            // Errors
            if( !response.success )
            {
                // No data came back, maybe a security error
                if( !response.data )
                    console.log( 'AJAX ERROR: no response' );
                // Error from PHP
                else
                    console.log( 'Response Error: ' + response.data.error );
            }
            // Success
            else
                console.log( 'Response Success: ' + response.data );
        }
    ); 
});

这是使用OOP和jQuery命令触发操作的similar answer of mine。还有article of interest