Проблема: перезагрузка страницы при изменении количества товаров в корзине WooCommerce
По умолчанию WooCommerce обновляет корзину при изменении количества товара с полной перезагрузкой страницы. Это снижает удобство пользователя и увеличивает нагрузку на сервер. Задача — реализовать динамическое обновление количества товаров и стоимости корзины через AJAX, чтобы страница не перезагружалась.
Диагностика проблемы
Чтобы подтвердить проблему, откройте страницу корзины и измените количество товара. Если после изменения происходит полная загрузка страницы, значит AJAX обновления не настроено.
Также проверьте консоль браузера (F12 → Console) на наличие JavaScript ошибок, которые могут блокировать работу скриптов WooCommerce.
Пошаговое решение: добавляем AJAX обновление корзины
1. Подключаем скрипт для AJAX обновления
Добавьте следующий код в functions.php вашей дочерней темы или в кастомный плагин:
function wpdownload_enqueue_ajax_cart_script() {
if (is_cart()) {
wp_enqueue_script('wpdownload-ajax-cart', get_stylesheet_directory_uri() . '/js/ajax-cart.js', array('jquery', 'wc-cart-fragments'), '1.0', true);
wp_localize_script('wpdownload-ajax-cart', 'wpdownload_ajax_params', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wpdownload-ajax-nonce')
));
}
}
add_action('wp_enqueue_scripts', 'wpdownload_enqueue_ajax_cart_script');В этом коде мы подключаем JavaScript-файл ajax-cart.js, который будет содержать логику AJAX. Также передаем параметры AJAX URL и nonce для безопасности.
2. Создаем JavaScript для обработки изменения количества
Создайте файл ajax-cart.js в папке вашей темы /js/ и добавьте туда:
jQuery(function($) {
$('form.woocommerce-cart-form').on('change', 'input.qty', function() {
var $input = $(this);
var newQty = $input.val();
var cartItemKey = $input.closest('tr').attr('data-cart-item-key');
if (!cartItemKey) {
return;
}
$.ajax({
url: wpdownload_ajax_params.ajax_url,
type: 'POST',
data: {
action: 'wpdownload_update_cart_quantity',
cart_item_key: cartItemKey,
quantity: newQty,
nonce: wpdownload_ajax_params.nonce
},
success: function(response) {
if (response.success) {
// Обновляем фрагменты корзины
$(document.body).trigger('wc_fragment_refresh');
// Обновляем содержимое корзины
$('div.woocommerce-cart-form').html(response.data.cart_html);
} else {
alert('Ошибка обновления корзины.');
}
},
error: function() {
alert('Ошибка AJAX запроса.');
}
});
});
});Этот скрипт слушает изменения в полях количества и отправляет запрос на сервер для обновления корзины без перезагрузки.
3. Реализуем PHP обработчик AJAX-запроса
Добавьте в functions.php следующий код:
function wpdownload_ajax_update_cart_quantity() {
check_ajax_referer('wpdownload-ajax-nonce', 'nonce');
$cart_item_key = sanitize_text_field($_POST['cart_item_key']);
$quantity = intval($_POST['quantity']);
if ($quantity < 0) {
wp_send_json_error(array('message' => 'Количество не может быть отрицательным'));
}
if (WC()->cart->set_quantity($cart_item_key, $quantity, true)) {
WC()->cart->calculate_totals();
ob_start();
wc_get_template('cart/cart.php');
$cart_html = ob_get_clean();
wp_send_json_success(array('cart_html' => $cart_html));
} else {
wp_send_json_error(array('message' => 'Не удалось обновить количество'));
}
wp_die();
}
add_action('wp_ajax_wpdownload_update_cart_quantity', 'wpdownload_ajax_update_cart_quantity');
add_action('wp_ajax_nopriv_wpdownload_update_cart_quantity', 'wpdownload_ajax_update_cart_quantity');Этот обработчик проверяет nonce, обновляет количество товара в корзине, пересчитывает итоги и возвращает обновленную верстку корзины.
Как проверить, что решение работает
- Откройте страницу корзины и измените количество товара в поле.
- Обратите внимание, что страница не перезагружается.
- Количество товара и сумма в корзине обновляются динамически.
- В консоли браузера отсутствуют ошибки JavaScript и AJAX.
- При отключенных кэшах и плагинах оптимизации AJAX корректно отрабатывает.
Частые ошибки и как их исправить
- Не подключен скрипт или неверный путь к
ajax-cart.js— проверьте путь и наличие файла в теме. - Отсутствует атрибут
data-cart-item-keyв строках корзины — добавьте его через фильтрwoocommerce_cart_item_keyили используйте другой селектор для идентификации товара. - Ошибка nonce — проверьте, что nonce передается и проверяется правильно.
- Неверная обработка ответа AJAX — убедитесь, что PHP возвращает JSON с нужными данными.
- Кэширование страницы блокирует AJAX — исключите страницу корзины из кэша.
Практические советы по безопасности и производительности
- Используйте
check_ajax_refererдля защиты от CSRF-атак. - Минимизируйте объем возвращаемых данных — можно возвращать только обновленные части, а не всю страницу корзины.
- Отключайте кэширование на страницах с динамическим содержимым (корзина, оформление заказа).
- Проверяйте и валидируйте входящие данные — количество должно быть целым положительным числом.
- При большом количестве товаров в корзине рекомендуется оптимизировать шаблон и AJAX-логику, чтобы не перегружать сервер.
Сравнение вариантов реализации AJAX обновления корзины
| Метод | Плюсы | Минусы |
|---|---|---|
| Использовать стандартные скрипты WooCommerce (wc-cart-fragments) | Легко интегрируется, поддерживается разработчиками WooCommerce | Ограниченная гибкость, обновляет только мини-корзину, а не всю страницу |
| Кастомный AJAX с полным обновлением корзины (как в статье) | Полный контроль над обновлением, можно обновлять любые элементы корзины | Требует написания и поддержки кода, возможны ошибки при обновлении верстки |
| Плагины для AJAX корзины (например, WooCommerce AJAX Cart) | Быстрое внедрение, обычно с дополнительными функциями | Зависимость от стороннего кода, возможные конфликты, платные решения |