为什么我的ajax功能没有按预期工作?

时间:2015-08-02 11:56:46

标签: ajax wordpress hook

所以我的班级看起来像这样:

class Myclass{

    private $nonce;

    public function __construct(){
        if( get_current_screen()->id == 'nav-menus' ){
            $this->nonce = 'my-plugin-nonce';
        }
        add_action( 'wp_ajax_run_action', array( $this, 'run' ) );

        wp_localize_script(
            'my-script',
            'my_script',
            array( 'nonce' => wp_create_nonce( $this->nonce ), 
                 'ajaxurl' => admin_url('admin-ajax.php'),
            )
        );
    }

    public function run(){
        if( ! wp_verify_nonce( $_POST['nonce'], $this->nonce ) )
            return false;

        wp_send_json_success();
    }

}
new Myclass;

这是javascript代码:

$.ajax({
    type: 'POST',
    dataType: 'json',
    url: my_script.ajaxurl,
    data: {
         'action': 'run_action',
         'nonce' : my_script.nonce,
    },
    complete: function( object ) {
        console.log( object.responseJSON )
    }
});

问题在于,当我尝试从我的javascript ajax函数中调用run_action操作时,它不会返回true。

请注意,我已正确本地化了我的脚本,并且正确呈现了对象中包含的所有数据。

为什么会这样?

2 个答案:

答案 0 :(得分:2)

脚本的本地化必须在包含脚本的页面上进行(例如,在本例中的nav-menus.php管理页面上) - 你不包含实际排列你的javascript的代码,但是您发布的代码告诉我,您实际上是在尝试本地化ajax-call本身的脚本 - 这不会起作用。

我已在下面重新安排了您的代码,并添加了评论以解释每项更改:

class Myclass {
    /**
     * No reason not to assign this already (and I've renamed it to explicitly,
     * let people reading the code know that it is not the nonce itself, but the
     * name of the nonce action - fooled me for a minute or two :p
     */
    private $nonce_action_name = 'my-plugin-nonce';

    /**
     * The __construct function is great for hooking everything you need to
     * hook, and for setting initial variables. Pretty much anything else
     * should NOT be in this function though!
     */
    public function __construct(){
        // Register your ajax action.
        add_action( 'wp_ajax_run_action', array( $this, 'run' ) );

        // Hook into the appropriate action for admin scripts
        add_action( 'admin_enqueue_scripts', array( $this, 'scripts' ) );
    }

    public function scripts() {
        /**
         * I've negated your if-statement here - basically we don't want to do
         * anything at all if we are not on the correct page - which is clearer
         * this way - also you had it in the __construct function, which will
         * actually produce a fatal error, since get_current_screen is not
         * usually defined yet at that point(!)
         */
        if( get_current_screen()->id !== 'nav-menus' ){
            return;
        }

        //Now enqueue (or register) the script
        wp_enqueue_script('my-script', plugins_url('/my-script.js', __FILE__));

        //Then localize it
        wp_localize_script(
            'my-script',
            'my_script',
            array(
                'nonce' => wp_create_nonce( $this->nonce_action_name ),
                'ajaxurl' => admin_url('admin-ajax.php'),
            )
        );
    }
    /**
     * Actual ajax handler
     */
    public function run(){
        if( ! wp_verify_nonce( $_POST['nonce'], $this->nonce_action_name ) ) {
            //This is a guess, but I think you'll want to wp_send_json_error
            //here to match up with your success below
            wp_send_json_error();
        } else {
            wp_send_json_success();
        }
        /**
         * Always recommended to explicitly die() after handling ajax - though
         * the wp_send_json_* family probably does it for you.
         */
        die();
    }
}
new Myclass;

最后要注意的是,ajaxurl实际上总是在管理员中定义,因此您并不需要将其添加到您的本地化中(尽管只需添加一些额外的字节就会受到伤害)。 / p>

答案 1 :(得分:1)

来自codex的注释:

  

wp_localize_script()必须在使用wp_register_script()wp_enqueue_script()注册脚本后调用。

因此,您的工作流程应如下所示:

  1. 注册脚本
  2. 本地化
  3. 将您的本地化脚本排入队列。
  4. 将其绑定到适当的操作:wp_enqueue_scriptsadmin_enqueue_scripts
  5. 例如:

    __construct方法添加操作:

    add_action('wp_enqueue_scripts', array($this, 'registerAjaxScript'));
    

    然后创建一个注册和本地化脚本的方法:

    function registerAjaxScript() {
      wp_register_script('my-script', 
             string $src, 
             array $deps, 
             string or bool $ver, 
             bool $in_footer
      );
      wp_localize_script('my-script',
            'my_script',
            array( 'nonce' => wp_create_nonce( $this->nonce ), 
                 'ajaxurl' => admin_url('admin-ajax.php'),
            )
      );
    }