WP check_ajax_referer()不起作用

时间:2019-10-20 作者:Ataur Rahman

我正在使用ajax开发预订表单。我面临两个问题。一种是当我在页面或帖子中使用表单的短代码时,在WP后端5.2.3版本中显示表单。另一个是当我使用这个函数check\\u ajax\\u referer()检查nonce字段时。表单不显示在“查看”页面中。仅在视图页面中显示-1。

/*
Plugin Name: Ajax Reservation Form
Plugin URI: http://example.com
Description: Reservation Form
Version: 1.0
Author: Ataur Rahman
Author URI: md-ataur.github.io
License: GPL v2 or later
License URI:  https://www.gnu.org/licenses/gpl-2.0.html
Text Domain:  ajax-reservation-form
*/
defined( \'ABSPATH\' ) or die( \'No script kiddies please!\' );
if(!class_exists(\'AjaxReservationForm\')){
    class AjaxReservationForm{
        public function __construct(){
            add_action(\'plugins_loaded\', array($this, \'ajaxrf_load_textdomain\' ));
            add_action(\'wp_enqueue_scripts\', array($this, \'ajaxrf_enqueue_scripts\'));
            add_shortcode( \'ajax_reservation_form\', array($this,\'ajaxrf_shortcode\' ));
            add_action( \'wp_ajax_ajaxRSF\', array($this, \'AjaxdataProcess\') );
            add_action( \'wp_ajax_nopriv_ajaxRSF\', array($this, \'AjaxdataProcess\') );
        }
        public function ajaxrf_load_textdomain(){
            load_plugin_textdomain( \'ajax-reservation-form\', false, dirname( plugin_basename( __FILE__ ) ) . \'/languages\' );
        }
        public function ajaxrf_enqueue_scripts(){
            wp_enqueue_style( \'bootstrap\', plugin_dir_url( __FILE__ ).\'assets/public/css/bootstrap.min.css\');
            wp_enqueue_script( \'ajax-reservation-js\', plugin_dir_url( __FILE__ ).\'assets/public/js/ajax-reservation.js\', array( \'jquery\' ), time(), true );
            $ajaxUrl = admin_url( \'admin-ajax.php\');
            wp_localize_script( \'ajax-reservation-js\', \'url\', array(\'ajaxUrl\' => $ajaxUrl) );
        }

        public static function AjaxdataProcess(){
            if (check_ajax_referer( \'rsf_nonce_action\', \'snonce\' )) {
                $RFname     = sanitize_text_field( isset($_POST[\'RFname\'])?$_POST[\'RFname\']:\'\' );
                $RFemail    = sanitize_text_field( isset($_POST[\'RFemail\'])?$_POST[\'RFemail\']:\'\' );
                $RFphone    = sanitize_text_field( isset($_POST[\'RFphone\'])?$_POST[\'RFphone\']:\'\' );
                $RFperson   = sanitize_text_field( isset($_POST[\'RFperson\'])?$_POST[\'RFperson\']:\'\' );
                $RFdate     = sanitize_text_field( isset($_POST[\'RFdate\'])?$_POST[\'RFdate\']:\'\' );
                $RFtime     = sanitize_text_field( isset($_POST[\'RFtime\'])?$_POST[\'RFtime\']:\'\' );
                $RFMessage  = sanitize_text_field( isset($_POST[\'RFMessage\'])?$_POST[\'RFMessage\']:\'\' );                 
                $data = array(
                    \'RFname\' => $RFname,
                    \'RFemail\' => $RFemail,
                    \'RFphone\' => $RFphone,
                    \'RFperson\' => $RFperson,
                    \'RFdate\' => $RFdate,
                    \'RFtime\' => $RFtime,
                    \'RFMessage\' => $RFMessage,
                );      
                echo "<pre>";
                print_r($data);
                echo "</pre>";  
            }
        }

        public static function ajax_reservation_form(){         
            ?>
            <div class="container">
                <div class="col-md-6 offset-md-3">
                    <form action="<?php the_permalink(); ?>" id="arform">
                        <?php wp_nonce_field( \'rsf_nonce_action\', \'rsf_nonce_field\');?>
                        <div class="form-group">
                            <label for="name" class="label">Name</label>                
                            <input type="text" class="form-control" id="RFname">                            
                        </div>
                        <div class="form-group">
                            <label for="email" class="label">Email</label>
                            <input type="email" class="form-control" id="RFemail">                           
                        </div>
                        <div class="form-group">
                            <label for="phone" class="label">Phone</label>                            
                            <input type="text" class="form-control" id="RFphone">
                        </div>
                        <div class="form-group">
                            <label for="persons" class="label">Number of Persons</label>
                            <select name="persons" id="RFperson" class="form-control">
                                <option value="1">1 person</option>
                                <option value="2">2 person</option>
                                <option value="3">3 person</option>
                                <option value="4">4 person</option>
                                <option value="5">5 person</option>
                            </select>                            
                        </div>
                        <div class="row">
                            <div class="form-group col-md-6">
                                <label for="date" class="label">Date</label>
                                <input type="date" class="form-control" id="RFdate">                                
                            </div>
                            <div class="form-group col-md-6">
                                <label for="time" class="label">Time</label>
                                <input type="time" class="form-control" id="RFtime" autocomplete="off">
                            </div>
                        </div>   
                        <div class="form-group">
                            <textarea class="form-control" id="RFMessage" rows="5"></textarea>
                        </div>                 
                        <div class="row justify-content-center">
                            <button id="reserveForm" class="btn btn-primary">Reserve Now</button>
                        </div>
                    </form>
                </div>
            </div>
            <?php
        }

        public function ajaxrf_shortcode(){
            self::AjaxdataProcess();
            self::ajax_reservation_form();
        }
    }
    new AjaxReservationForm;
}
Javascript

;(function($){
    $(document).ready(function(){       
        $(\'#reserveForm\').on(\'click\', function(){
            $.post(url.ajaxUrl, {
                action: \'ajaxRSF\',
                snonce: $(\'#rsf_nonce_field\').val(),
                RFname: $(\'#RFname\').val(),
                RFemail: $(\'#RFemail\').val(),
                RFphone: $(\'#RFphone\').val(),
                RFperson: $(\'#RFperson\').val(),
                RFdate: $(\'#RFdate\').val(),
                RFtime: $(\'#RFtime\').val(),
                RFMessage: $(\'#RFMessage\').val()
            }, function(data) {
                console.log(data);
            });         
            return false;
        });
    });
})(jQuery);

enter image description here

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

一种是当我在页面或帖子中使用表单的短代码时,在WP后端5.2.3版本中显示表单。

发生这种情况是因为您的短代码正在响应输出。短代码应始终返回输出,但如果需要回显输出,则应使用输出缓冲:

public function ajaxrf_shortcode(){
    // Turn on output buffering.
    ob_start();

    self::AjaxdataProcess();
    self::ajax_reservation_form(); // echo the form

    // Turn off output buffering and then return the output echoed via the above functions.
    return ob_get_clean();
}
另一个是使用此函数检查nonce字段时check_ajax_referer(). 表单不显示在“查看”页面中。仅在视图页面中显示-1。

首先,你为什么打电话来AjaxdataProcess() 在shortcode函数中(ajaxrf_shortcode())? 是因为您允许非AJAX表单提交吗?

但是,如果(AJAX)请求验证失败(例如,由于缺少或过期的nonce),并且默认情况下,“-1”可能会发生,check_ajax_referer() 将调用wp_die() 如果执行AJAX请求或die() 否则

为了防止WordPress/PHP在请求验证失败时停止执行,请将第三个参数设置为false 当你打电话的时候check_ajax_referer():

check_ajax_referer( \'rsf_nonce_action\', \'snonce\', false )

如果要允许非AJAX表单提交name; e、 g.:

<input type="text" class="form-control" id="RFname" name="RFname">
<input type="email" class="form-control" id="RFemail" name="RFemail">
method 到post (因为AjaxdataProcess() 正在使用$_POST):

<form action="<?php the_permalink(); ?>" id="arform" method="post">
snonce 具有check_ajax_referer() (在JS脚本中),但在表单中,名称是rsf_nonce_field:

英寸ajax_reservation_form() &mdash;the value of the second parameter for wp_nonce_field() should match the value of the second parameter for check_ajax_referer() (事实上,第一个参数也是如此……):

<?php wp_nonce_field( \'rsf_nonce_action\', \'rsf_nonce_field\');?>
rsf_nonce_field 应更改为snonce.