接受具有序列化表单数据的AJAX调用

时间:2013-10-19 作者:JimQ

我正在尝试通过ajax向wordpress插件传递一些表单数据,它工作正常,除非表单数据被序列化,否则服务器会以错误消息响应。这件事我已经坚持了好几天了,但我无法让它发挥作用。我做错了什么,这不会那么难吧?

以下是错误消息:

call\\u user\\u func\\u array()要求参数1为有效回调,在X:\\xampp\\htdocs\\testsite\\wp includes\\plugin中找不到函数“process\\u request”,或函数名无效。php在线406

AJAX调用:

jQuery(document).ready(function($) {

nonce: whatever

//if i use this variable, it works fine 
var data = {action: \'process_request\', add_my_data: \'whatever\', \'my_data[name]\':\'whatever\', my_nonce: nonce};

//if i use this variable, the server returns the above error .
//because .serialize() doesn\'t include the submit button\'s name
//and the form doesn\'t contain the name of the function to be called, i added them manually to the string. nonce is pulled from form.

var data2 =\'action=process_request&add_my_data=whatever&\' + $(\'#my-form\').serialize();


$(\'.my_submit_button\').click(function(event) {       
event.preventDefault(); 

jQuery.ajax({
type : \'post\',
url : ajaxurl,
timeout: 25000,
data : //data (works) or data2 (doesn\'t work),
[...]
奇怪的是,“data2”的post数据似乎没有问题,并且具有与“data”相同的语法。

我用firebug控制post数据:

对于“数据”:

action=process_request&add_my_data=whatever&my_data%5Bname%5D=whatever&my_nonce=1b444dd703 
对于“data2”(表单序列化后,我看到的唯一区别是referer):

action=process_request&add_my_data=whatever&my_data%5Bname%5D=whatever&my_nonce=1b444dd703&_wp_http_referer=%2Ftestsite%2Fadmin%2Ftestpage%2F
处理请求的PHP函数:

function process_request() {

    //nonce validation left out for readability

    if( isset ($_POST[\'add_my_data\']) ) {
        $this->add_info_array(\'placeholder\', \'Database updated\');
    }
            //do some stuff here
            die();
        }
      add_action(\'wp_ajax_process_request\', \'process_request\');
更新:问题是为“data2”创建的字符串中的referer。请查看下面我的评论。

2 个回复
SO网友:Jay Wood

在WordPress中使用AJAX和表单时,我喜欢将AJAX操作编码到表单中,这样序列化就可以开箱即用了。事实上,去年我写了一篇关于这个的文章:https://webdevstudios.com/2015/02/12/handling-ajax-in-wordpress/

但是,你是来寻求答案的,不是一篇博客文章,所以这里是简短的部分。这里有三个部分,第一部分是HTML表单。你可以利用serialize() 通过将操作放置在隐藏的表单字段中,下面是一个示例:

<form class="my_form">
    <?php wp_nonce_field( \'my_action_nonce\' ); ?>
    <input type="hidden" name="action" value="my_action" />
    <!-- More fields here... -->
    <input type="submit" name="submit" value="Submit" class="submit_form_btn" />
</form>
请注意名为action. 我当然保留了wp_nonce_field() 因为安全问题。

第二部分是实际的jQuery,如前所述,您不需要通过原始jQuery对象访问AJAX,因为您已经将其作为$, 但这并没有伤害任何东西,只是坏习惯。

jQuery( document ).ready( function( $ ) {
    $( \'.submit_form_btn\' ).on( \'click\', function( evt ) {
        // Stop default form submission
        evt.preventDefault();
        // Serialize the entire form, which includes the action
        var serialized = $( \'.my_form\' ).serialize();
        $.ajax( {
            url: ajaxurl, // This variable somewhere
            method: \'POST\',
            data: serialized, // This is where our serialized data is
        } ).done( function( result ){
            // Handle the result here...
        } );
    } );
} );
我尽可能地对代码进行注释,这应该更有意义,但让我解释一下。首先,通过preventDefault() 的方法evt 对象(事件的缩写)。

然后序列化表单数据并将其存储在变量中。我想您可以将其设置为快捷方式,然后将其放入数据对象中,但这取决于您。

最后一部分,你需要看看你在发布什么,对吗?那就是error_logprint_r 请随时使用,以下是操作方法:

<?php

function handle_ajax() {
    // Here you verify your nonce
    if ( ! wp_verify_nonce( $_POST[\'_wpnonce\'], \'my_action_nonce\' ) ) {
        // You can either return, or use nifty json stuffs
        wp_send_json_error();
    }
    // Here you should get ALL your data in a $_POST variable
    // or you can actually do someting like this then check your error log

    error_log( print_r( $_POST, 1 ) );

    // This will print out the ENTIRE $_POST variable to your debug.log if you have it
    // enabled, if not, it goes to your PHP error log

}
add_action( \'wp_ajax_my_action\', \'handle_ajax\' );
现在应该可以为您处理ajax了,如何处理数据取决于您自己。

SO网友:josh

为什么要使用jQuery.ajax?

定义时jQuery(document).ready(function($) {... $ 成为全局jquery变量。WordPress jQuery noConflict Wrapper

您的ajax应该类似于:

$.ajax({
type : \'post\',
url : ajaxurl,
etc : ....
接下来,您不能只传递一串变量。您需要首先将它们定义到一个对象中,并传递该对象。

尝试以下操作:

get_data = $(\'#my-form\').serialize();
var data = {action: \'process_request\', add_my_data: get_data, my_nonce: nonce};
但不确定序列化。。。正如我所想,WordPress在ajax发布过程中已经做到了这一点。你可能需要在那里做更多的研究。

结束