WooCommerce: правильное удаление товаров из корзины через AJAX без перезагрузки страницы

Диагностика проблемы: почему стандартное удаление товара из корзины вызывает перезагрузку страницы

По умолчанию WooCommerce реализует удаление товаров из корзины через ссылку с GET-параметром, что приводит к полной перезагрузке страницы корзины или страницы с мини-корзиной. Это снижает UX, особенно на мобильных устройствах и при большом потоке пользователей. Многие пытаются обойти это, добавляя AJAX-запросы, но часто сталкиваются с тем, что корзина не обновляется корректно или количество товаров не меняется визуально.

Основная причина — отсутствие правильного обновления сессии WooCommerce и фрагментов мини-корзины после удаления товара через AJAX.

Пошаговое решение: удаление товара из корзины через AJAX с обновлением мини-корзины

1. Добавляем JavaScript для отправки AJAX-запроса на удаление товара

Вставьте следующий код в файл темы (например, functions.php) для подключения скрипта и передачи параметров AJAX:

function wpnulled_enqueue_ajax_cart_script() {
    wp_enqueue_script('wpnulled-ajax-cart', get_stylesheet_directory_uri() . '/js/ajax-remove-cart.js', array('jquery'), null, true);
    wp_localize_script('wpnulled-ajax-cart', 'wpnulled_ajax_obj', array(
        'ajax_url' => admin_url('admin-ajax.php'),
        'cart_nonce' => wp_create_nonce('wpnulled_cart_nonce')
    ));
}
add_action('wp_enqueue_scripts', 'wpnulled_enqueue_ajax_cart_script');

Создайте файл ajax-remove-cart.js в папке js вашей темы со следующим содержимым:

jQuery(document).ready(function($) {
    $('body').on('click', '.wpnulled-remove-from-cart', function(e) {
        e.preventDefault();
        var cart_item_key = $(this).data('cart_item_key');

        $.ajax({
            type: 'POST',
            url: wpnulled_ajax_obj.ajax_url,
            data: {
                action: 'wpnulled_remove_cart_item',
                cart_item_key: cart_item_key,
                nonce: wpnulled_ajax_obj.cart_nonce
            },
            success: function(response) {
                if(response.success) {
                    // Обновляем фрагменты корзины
                    if(response.data.fragments) {
                        $.each(response.data.fragments, function(key, value) {
                            $(key).replaceWith(value);
                        });
                    }
                } else {
                    alert('Ошибка при удалении товара из корзины');
                }
            }
        });
    });
});

2. Обрабатываем AJAX-запрос в PHP

Добавьте в functions.php следующий обработчик:

function wpnulled_ajax_remove_cart_item() {
    check_ajax_referer('wpnulled_cart_nonce', 'nonce');

    if ( ! isset($_POST['cart_item_key']) ) {
        wp_send_json_error();
    }

    $cart_item_key = sanitize_text_field($_POST['cart_item_key']);
    $cart = WC()->cart;

    if ( $cart->remove_cart_item($cart_item_key) ) {
        WC()->cart->calculate_totals();
        WC()->cart->maybe_set_cart_cookies();

        // Получаем обновлённые фрагменты мини-корзины
        ob_start();
        woocommerce_mini_cart();
        $mini_cart = ob_get_clean();

        $fragments = array(
            'div.widget_shopping_cart_content' => '<div class="widget_shopping_cart_content">' . $mini_cart . '</div>'
        );

        wp_send_json_success( array( 'fragments' => $fragments ) );
    } else {
        wp_send_json_error();
    }
}
add_action('wp_ajax_wpnulled_remove_cart_item', 'wpnulled_ajax_remove_cart_item');
add_action('wp_ajax_nopriv_wpnulled_remove_cart_item', 'wpnulled_ajax_remove_cart_item');

3. Добавляем кнопку удаления с нужным классом и data-атрибутом в шаблон корзины

В файле шаблона корзины (например, cart.php или мини-корзины) замените стандартную ссылку на удаление на следующий html-код:

<a href="#" class="wpnulled-remove-from-cart" data-cart_item_key="<?php echo esc_attr( $cart_item_key ); ?>" title="Удалить товар">×</a>

Это позволит JavaScript отловить клик и отправить AJAX-запрос.

Проверка результата после внедрения

  • Откройте страницу корзины на фронтенде.
  • Нажмите на кнопку удаления товара (крестик).
  • Обратите внимание, что страница не перезагружается.
  • Товар должен исчезнуть из списка, а мини-корзина в шапке (если есть) обновиться.
  • Проверьте, что количество товаров и итоговая сумма изменились.

Частые ошибки и причины

  • Не обновляются фрагменты корзины: не возвращён или не обработан в JS правильный HTML мини-корзины.
  • Ajax-запрос не срабатывает: ошибки в JavaScript, отсутствует локализация скрипта или неправильные селекторы.
  • Ошибка безопасности (nonce): не передан или не проверен nonce, что блокирует выполнение запроса.
  • Корзина не пересчитывается: забыли вызвать calculate_totals() и maybe_set_cart_cookies() после удаления.

Практические советы по производительности и безопасности

  • Используйте wp_localize_script для передачи параметров AJAX, включая nonce для безопасности.
  • Обрабатывайте AJAX-запросы с проверкой nonce через check_ajax_referer.
  • Для повышения скорости загрузки мини-корзины кэшируйте фрагменты, но не забывайте обновлять их после изменения корзины.
  • Минимизируйте объем возвращаемого HTML в AJAX-ответе, отправляя только необходимые фрагменты.

Сравнение способов удаления товара из корзины

МетодПлюсыМинусыКомпромисс
Стандартная ссылка удаления (GET)Простая реализация, работает из коробкиПерезагрузка страницы, плохой UXПодходит для простых сайтов без AJAX
Удаление через AJAX с обновлением фрагментовБыстрое удаление без перезагрузки, лучше UXСложнее в реализации, требует поддержки JS и корректной работы сессийОптимальный вариант для современных магазинов
Удаление через AJAX с полным обновлением страницыУпрощение совместимости, частично сохраняет UXЗадержка и лишняя перезагрузка части страницыМожно использовать как временное решение
Отключение кеширования страниц корзины в WooCommerce
01.08.2026
WooCommerce: правильное удаление товаров из корзины через AJAX без перезагрузки страницы
04.08.2026