web-dev-qa-db-ja.com

受ける入る AJAX シリアル化されたフォームデータを使って呼出す

私はAjaxを介していくつかのフォームデータをワードプレスのプラグインに渡すことを試みている、それはフォームデータがシリアル化されていない限り、それは正常に動作し、その後サーバーはエラーメッセージで応答します。私は今何日もこれで立ち往生しています、しかし私はそれを働かせることができません。私は何を間違っています、これはそんなに難しいことはできませんね。

これがエラーメッセージです。

call_user_func_array()は、パラメータ1が有効なコールバックであること、関数 'process_request'が見つからないこと、またはX:\ xampp\htdocs\testsite\wp-includes\plugin.php内の無効な関数名であることを期待します

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'の投稿データは問題ないようで、 'data'の場合と同じ構文です。

私はfirebugで投稿データを管理しました:

'data'の場合:

action=process_request&add_my_data=whatever&my_data%5Bname%5D=whatever&my_nonce=1b444dd703 

'data2'の場合(直列化された形式では、唯一の違いは参照元です):

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'のために作成された文字列の中の参照元です。下記の私のコメントをチェックしてください。

1
JimQ

WordPressでAJAXとFormsを使って作業するときは、フォームへのajaxアクションをコーディングするのが好きなので、シリアル化はそのまま使用できます。実際に私はこの昨年の記事を書きました: https://webdevstudios.com/2015/02/12/handling-ajax-in-wordpress/

しかし、ブログ記事ではなく回答のためにここにいるので、その短い部分がここにあります。ここには3つの部分があります。最初は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()を続けてきました。

2番目の部分は実際の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...
        } );
    } );
} );

私はできる限りコードをコメントしようとしました、それはもっと理にかなっているはずですが、説明させてください。まずevtオブジェクトのpreventDefault()メソッドでフォームの送信を止めます(eventの略)。

その後、フォームデータをシリアル化して変数に格納します。私はあなたがそれをショートカットして単にデータオブジェクトにそれを落とすことができると思います、しかしそれはあなた次第です。

最後に、投稿内容を正しく確認する必要がありますか。 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をあなたが扱うべきであるので、あなたがデータを使ってすることはあなた次第です。

2
Jay Wood

なぜあなたはjQuery.ajaxを使っているのですか?

jQuery(document).ready(function($) {...を定義すると、$がグローバルjquery変数になります。 WordPress jQuery noConflictラッパー

あなたの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ポストプロセスの間に行っていたと思います。もっと調査する必要があるかもしれません。

0
josh