Не передаётся корректно action при AJAX.
Не получается сделать ajax-запрос.
Стоит задача сделать калькулятор калорий и индекса массы тела. Расчёты производятся в бэкенде в плагине, фронт js передаёт данные из формы.
HTML:
<form action="bmi" class="calculator__form" id="calcForm" method="POST"> <input type="text" name="height" class="calculator__input input__height" placeholder="Введите ваш рост (см)"> <input type="text" name="weight" class="calculator__input input__weight" placeholder="Введите ваш вес (кг)"> <input type="text" name="age" class="calculator__input input__age" placeholder="Введите ваш возраст"> <select name="gender" id="" class="calculator__input input__gender"> <option value="choose">Выберите ваш пол</option> <option value="male">Мужчина</option> <option value="female">Женщина</option> </select> <select name="activity" id="" class="calculator__input input__activity"> <option value="choose">Выберите ваш уровень активности</option> <option value="1-to-3">Тренировки 1-3 раза в неделю</option> <option value="3-to-5">Тренировки 3-5 дней в неделю</option> <option value="sportsman">Спортсмены, тренировки чаще 1 раза в день</option> </select> </form>
JS-код:
'use strict'; let calcForm = document.querySelector('#calcForm'); calcForm.addEventListener('submit', function (e) { e.preventDefault(); let data = { 'action': 'bmi', 'height': +document.querySelector('input[name="height"]').value, 'weight': +document.querySelector('input[name="weight"]').value, 'age': +document.querySelector('input[name="age"]').value, 'gender': document.querySelector('select[name="gender"]').value, 'activity': document.querySelector('select[name="activity"]').value } let xhr = new XMLHttpRequest(); xhr.open('POST', myAjax.ajaxurl, true); xhr.responseType = 'json'; xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8'); xhr.send(JSON.stringify(data)); xhr.addEventListener('load', () => { console.log(xhr.response); }); });
PHP-код в плагине:
<?php /* Plugin Name: bmi */ add_action( 'wp_ajax_bmi', 'count_bmi' ); add_action( 'wp_ajax_nopriv_bmi', 'count_bmi' ); add_action( 'wp_enqueue_scripts', 'include_bmi_scripts' ); function count_bmi() { $height = $_POST['height']; $weight = $_POST['weight']; $age = $_POST['age']; $gender = $_POST['gender']; $activity = $_POST['activity']; $bmi = 0; $bmr = 0; $bmra = 0; $message = ""; $image = ""; $bmi = $weight / (($height / 100) * ($height / 100)); if ($gender == 'male') { $bmr = 88.36 + (13.4 * $weight) + (4.8 * $height) - (5.7 * $age); } else { $bmr = 447.6 + (9.2 * $weight) + (3.1 * $height) - (4.3 * $age); } if ($activity == 'desk') { $bmra = $bmr * 1.2; } else if ($activity == '1-to-3') { $bmra = $bmr * 1.375; } else if ($activity == '3-to-5') { $bmra = $bmr * 1.55; } else if ($activity == '6-to-7') { $bmra = $bmr * 1.725; } else if ($activity == 'sprotsman') { $bmra = $bmr * 1.9; } else { $bmra = 0; } $out = array ( 'message' => $message, 'bmi' => $bmi, 'bmr' => $bmr, 'bmra' => $bmra ); header('Content Type: text/json; charset=utf-8'); echo json_encode($out); } function include_bmi_scripts() { wp_enqueue_script('bmi-js', plugins_url( 'bmi.js', __FILE__ ), array(), false, true); wp_localize_script('bmi-js', 'myAjax', array('ajaxurl'=>admin_url('admin-ajax.php'))); }
JS-скрипт отрабатывает корректно ровно до того момента, как вызывается метод send() у объекта класса XMLHttpRequest.
Если поменять myAjax.ajaxurl на сторонний фейковый api url, то приходят корректные ответы от сервера и возвращаются нужные данные. Но как только дело доходит до отправки запроса в admin-ajax.php, то вылазит 400-я ошибка, а сервер возвращает 0.
Я посмотрел код и знаю, что 0 возвращается в случае некорректного action либо его отсутствия. Но как мне ещё его передать, я ума не приложу. Я пробовал добавлять его в url (myAjax.ajaxurl + '?action=bmi') - не работает; я пробовал передавать не json, а FormData (но у меня почему-то данные туда даже аппендиться не хотели, после всех append оставался пустой объект). И что я только не делал, но результат всё равно один и тот же.
Вопрос: где я косячу? Как мне передать action при помощи чистого js?
P.S. fetch тоже пробовал, не хочет работать. Сделать хочу именно на чистом js, чтобы понимать по шагам, что происходит вообще и не быть завязанным на фреймворки.
Оставлю на всякий случай ссылку на форум. Задавал там свой вопрос, можно прочитать уже данные мне советы, что я там пробовал и какие были результаты, чтобы не тратить время впустую. А перепробовал реально много чего.
P.S. делаю на виртуальном сервере xampp.
https://www.cyberforum.ru/wordpress/thread2999829.html
Там пример есть
Для начала отправьте простой запрос:
Это не работает. Я пробовал экшн передавать по ссылке - 500 ошибка выскакивает. Урл правильный, отправляет в /wp-admin/admin-ajax.php.
https://stackoverflow.com/questions/9713058/send-post-data-using-xmlhttprequest
вот там РАБОЧИЙ пример.
Код проверил локально - и он работает.
Как получить в таком виде переменную params - уже сами разберетесь.
ЗАМЕЧУ: если у вас при базовом запросе НЕТ вообще ответа от сервера - значит вы НЕ отправляете туда запрос.
У меня при неправ передаче данных - в $_POST был пустой массив.
У вас же - как вы пишите, вообще сервер НЕ отвечает, что есть бредом.
Значит вы не отправл туда, а именно на admin-ajax.php данные ИЛИ они блокируются кем-то чем-то.
Базово все работает "с коробки".
Во-первых вместо
должно быть
Во-вторых вместо
есть нативный вордпресовский вывод
Пробовал и JSON.stringify, и просто data, и FormData отправлять. Не работает. Пробовал через fetch и jquery отправлять. На сторонних апишках всё ок, отрабатывает корректно, но как только дело касается вордпресса, то он почему-то не видит экшн. Попытка передать его через урл тоже ни к чему не привела.
Насчёт вордпрессовского родного вывода - не знал. Спасибо. Делал многое по ютубу и гуглу, видел там реализацию, которая у меня сейчас.
Вы так и не отписали, вы заменили ли код в обоих местах и что теперь получается?
Проблема в том что ваш код
должен иметь третью строчку
именно из-за этого у вас 400 с выводом 0
Всё равно 400-я ошибка. Фишка там даже не в php-коде, почему-то admin-ajax.php просто не видит action. А если ему его передавать насильно ссылкой, то 500-я ошибка вообще вылазит
Как вам уже написал уважаемый Stepan, допишите в вашей функции хука в самом начале
и посмотрите что возвращает в ответе в консоле.
А в JS допишите здесь после 'use strict'
Нужно посмотреть все ли там правильно.