AJAX обработчик выдает 400 (Неверный запрос) – почему?

Вопрос или проблема

Я пытаюсь применить функцию “Загрузить больше постов” к циклу постов, но сталкиваюсь с ошибкой 400 Bad Request, когда запрашиваю admin-ajax.php.

Ссылка, которую я использовал, – https://rudrastyh.com/wordpress/load-more-posts-ajax.html

Следующая функция (в functions.php) передает параметры запроса в JavaScript:

function wordpress_my_load_more_scripts() 
{
    global $wp_query; 

    wp_enqueue_script('jquery');

    wp_register_script( 'my_loadmore', get_stylesheet_directory_uri() . '/myloadmore.js', array('jquery') );

    wp_localize_script( 'my_loadmore', 'wordpress_loadmore_params', array(
        'ajaxurl' => admin_url() . 'admin-ajax.php', 
        'posts' => json_encode( $wp_query->query_vars ), 
        'current_page' => get_query_var( 'paged' ) ? get_query_var('paged') : 1,
        'max_page' => $wp_query->max_num_pages
    ) );

    wp_enqueue_script( 'my_loadmore' );
}

add_action( 'wp_enqueue_scripts', 'wordpress_my_load_more_scripts' );

Параметры передаются в следующий скрипт jQuery, названный “myloadmore.js”:

jQuery(function($){
    $('.wordpress_loadmore').click(function()
    { 
        var button = $(this),
            data = {
            'action': 'loadmore',
            'query': wordpress_loadmore_params.posts, 
            'page' : wordpress_loadmore_params.current_page
        };

        console.log(wordpress_loadmore_params.ajaxurl);

        $.ajax({
            url : wordpress_loadmore_params.ajaxurl, // AJAX обработчик
            data : data,
            type : 'POST',
            beforeSend : function ( xhr ) 
            {
                button.text('Загрузка...'); 
            },
            success : function( data ){
                if( data ) { 
                    button.text( 'Больше постов' ).prev().before(data); 
                    wordpress_loadmore_params.current_page++;

                    if ( wordpress_loadmore_params.current_page == wordpress_loadmore_params.max_page ) 
                        button.remove(); // если последняя страница, убираем кнопку

                } else {
                    button.remove(); // если нет данных, убираем кнопку
                }
            }
        });
    });
});

Следующая функция в functions.php ожидается для предоставления трех дополнительных постов внутри цикла while:

function wordpress_loadmore_ajax_handler()
    {
        $args = json_decode( stripslashes( $_POST['query'] ), true );
        $args['paged'] = $_POST['page'] + 1; 
        $args['post_status'] = 'publish';

        query_posts( $args );

        if(have_posts() ) :

            echo "У нас есть пост(ы)!";

            while( have_posts() ): the_post();

                echo "Пост!";

            endwhile;

        endif;

        die; 
    } 

    add_action('wp_ajax_loadmore', 'wordpress_loadmore_ajax_handler'); 
    add_action('wp_ajax_nopriv_loadmore', 'wordpress_loadmore_ajax_handler'); 

Цикл постов выглядит так:

<ul class="products columns-3">

                    <?php 

                    $query_params = array(
                            'post_type' => 'post',
                            'posts_per_page' => 3
                    );

                    $wp_query = new WP_Query( $query_params);        

                    if( $wp_query->have_posts() ) :

                        while ($wp_query->have_posts()) : $wp_query->the_post(); ?>

                            <li class="product post-item">
                                <span class="post-image">
                                    <a href="https://wordpress.stackexchange.com/questions/302332/<?php the_permalink(); ?>">
                                        <?php 
                                            if ( has_post_thumbnail()) 
                                            {
                                                the_post_thumbnail();
                                            }
                                        ?>
                                    </a>
                                </span>
                                <h2 class="post-title"><a href="https://wordpress.stackexchange.com/questions/302332/<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></h2>
                                <span class="post-category"><?php the_category(', ');?></span>
                            </li>

                        <?php endwhile; ?>

                    <?php endif; ?>

                </ul>

                <nav>
                    <?php

                    global $wp_query; // вы можете убрать эту строку, если у вас все работает

                    // не показывать кнопку, если недостаточно постов
                    if (  $wp_query->max_num_pages > 1 )
                        echo '
                            <div class="wordpress_wrapper">
                                <div class="wordpress_loadmore">Больше постов</div>
                            </div>'; // вы также можете использовать <a>
                    ?>
                </nav>

                <?php wp_reset_postdata(); ?>

При нажатии кнопки для загрузки большего количества постов появляется следующее сообщение:

https://www.uvjagtpro.dk/wp-admin/admin-ajax.php
jquery.js?ver=1.12.4:4 POST https://www.uvjagtpro.dk/wp-admin/admin-ajax.php 400 ()
send @ jquery.js?ver=1.12.4:4
ajax @ jquery.js?ver=1.12.4:4
(anonymous) @ myloadmore.js:13
dispatch @ jquery.js?ver=1.12.4:3
r.handle @ jquery.js?ver=1.12.4:3

Почему я не могу разобрать переменную в массиве с именем “wordpress_loadmore_params.ajaxurl”, не вызывая ошибку 400 Bad Request?

Ссылка на страницу здесь – https://www.uvjagtpro.dk/arkiv/

В вашем HTML добавьте

 `<input name="action" type="hidden" value="test_function"/>` 

Здесь “value” – это ваше “action_name”. Ваш AJAX вызов неправильный. Данные должны быть

url: "ваш php action скрипт"
data: $(html data).serialize(),

Сначала попробуйте создать AJAX на своем компьютере без WordPress. Когда вы поймете, как работает AJAX, попробуйте на WordPress.

Ответ или решение

Ошибка 400 (Bad Request) в вашем AJAX-запросе может быть вызвана рядом причин, и в вашем случае это может быть связано с неправильной передачей данных в запросе, либо с тем, как обрабатываются параметры на стороне сервера. Давайте подробнее разберем возможные причины и рекомендации по их устранению.

1. Проблема с передачей данных

Когда вы создаете AJAX-запрос, важно правильно сериализовать и передавать данные. В вашем коде вы передаете параметры с помощью объекта:

var data = {
    'action': 'loadmore',
    'query': wordpress_loadmore_params.posts, 
    'page' : wordpress_loadmore_params.current_page
};

Убедитесь, что в переменной wordpress_loadmore_params.posts содержится корректный JSON, который можно декодировать на стороне сервера. Для проверки вы можете вывести это значение в консоль:

console.log(wordpress_loadmore_params.posts);

Если данные не корректны или содержат недопустимый символ, это может стать причиной возникновения ошибки 400.

2. Ошибки в обработчике AJAX

В функции wordpress_loadmore_ajax_handler вы используете json_decode() для обработки параметров. Убедитесь, что данные, которые вы передаете, корректно декодируются. Вы можете добавить проверку, чтобы увидеть, успешно ли производится декодирование:

$args = json_decode( stripslashes( $_POST['query'] ), true);
if (json_last_error() !== JSON_ERROR_NONE) {
    error_log('JSON Error: ' . json_last_error_msg());
    wp_send_json_error('Invalid JSON data.');
}

Эта проверка будет записывать ошибку в лог и возвращать сообщение, если данные некорректны.

3. Корректное указание действия

Убедитесь, что вы правильно указываете действие в AJAX-запросе. В вашем JavaScript-коде это:

'action': 'loadmore',

Убедитесь, что это значение совпадает с тем, что вы указали в функции add_action():

add_action('wp_ajax_loadmore', 'wordpress_loadmore_ajax_handler'); 
add_action('wp_ajax_nopriv_loadmore', 'wordpress_loadmore_ajax_handler');

4. Проблемы с URL

Проверьте, что admin_url() . 'admin-ajax.php' формирует корректный URL. Выведя этот URL в консоль, вы сможете убедиться, что к нему можно обратиться:

console.log(wordpress_loadmore_params.ajaxurl);

Если вы не видите admin-ajax.php в выводе консоли, это может говорить о том, что URL формируется неправильно.

5. Обработка ошибок на стороне клиента

Если вы всё еще получаете ошибку 400 после внесения вышеупомянутых изменений, попробуйте добавить обработчики ошибок в ваш AJAX-запрос. Это поможет вам более четко увидеть, что именно идет не так:

$.ajax({
    //...
    error: function(jqXHR, textStatus, errorThrown) {
        console.error('AJAX Error:', textStatus, errorThrown);
    }
});

Это позволит вам отследить сообщение об ошибке, которое генерируется сервером и может содержать подсказки для устранения проблемы.

Заключение

Общая ошибка 400 указывает на то, что что-то не так с запросом, который вы отправляете на сервер. Используя вышеуказанные рекомендации, вы сможете диагностировать, в чем именно заключается проблема. Проверьте корректность передаваемых данных, убедитесь в правильной настройке обработчика и URL, а также добавьте механизмы логирования и обработки ошибок. Это значительно упростит процесс нахождения и исправления ошибки.

Оцените материал
Добавить комментарий

Капча загружается...