Ajax запрос возвращает полную HTML страницу вместо ответа

20 июн. 2019 г., 00:06:13
Просмотры: 14.4K
Голосов: 1

Я знаю, что этот вопрос задавался часто, но ни одно из найденных решений мне не помогло.

Проблема следующая: при отправке формы в консоли я получаю полную HTML страницу вместо ожидаемого сообщения.

Backend скрипт:

    add_action( 'admin_ajax_nopriv_email_verification_form', 'verify_and_sanitize_email_form' );
add_action( 'admin_ajax_email_verification_form', 'verify_and_sanitize_email_form' );

// Функция проверки email
function verify_and_sanitize_email_form() {
    // Проверка реферера
    check_ajax_referer( '9pU0Pk7T01', 'security' );

    if(empty($_POST) || !isset($_POST['rguroo_email']) || !isset($_POST['rguroo_email_confirmation']) || !isset($_POST['rguroo_desired_action'])) {
        echo 'Одно или несколько полей пустые';
        wp_die();
    }
    $sanitized_email = sanitize_email( esc_html($_POST['rguroo_email'] ));
    $sanitized_email_confirmation = sanitize_email( esc_html($_POST['rguroo_email_confirmation'] ));
    $desired_action = esc_html($_POST['rguroo_desired_action']);

    if(!is_email( $sanitized_email ) || !is_email( $sanitized_email_confirmation )) {
        echo 'Email невалиден';
        wp_die();
    }

    if($sanitized_email !== $sanitized_email_confirmation) {
        echo 'Email адреса не совпадают';
        wp_die();
    }

    if($desired_action !== 'purchase' || $desired_action !== 'renewal' || $desired_action !== 'trial') {
        echo 'Ошибка с радио кнопками';
        wp_die();
    }

    if(!isset($_COOKIE['rguroo_form_type'])) {
        echo 'Ошибка сервера';
        wp_die();
    }

    // Логика проверки студенческого email
    $form_type = $_COOKIE['rguroo_form_type'];
    if($form_type === 'student') {
        $trail = substr($sanitized_email, -4);
        if($trail !== '.edu') {
            echo 'Невалидный студенческий email';
            wp_die();
        }
        // Другая университетская логика здесь
    }
    setcookie('rguroo_form_action',$desired_action, 14 * DAY_IN_SECONDS);
    setcookie('rguroo_form_email', $sanitized_email, 14 * DAY_IN_SECONDS);
    echo "success";
    wp_die();
}

Frontend javascript:

jQuery(document).ready(function () {
  jQuery('form#email-verification').on( 'submit', function () {
    var form_data = jQuery(this).serializeArray();
    form_data.push( { "name" : "security", "value" : ajax_info.ajax_nonce } );
    jQuery.ajax({
          url : ajax_info.ajax_url,
          type : 'post',
          data : form_data,
          success : function( response ) {
              console.log(response);
              if(response !== 'success') {
                jQuery('.error').innerHTML = response;
              } else {
                location.reload();
              }
          },
          fail : function( err ) {
              jQuery('.error').innerHTML = "Не удалось связаться с сервером";
          }
      });
    return false;
  });
});

Форма (используется в шорткоде):

function output_email_verification() {
    return '<form action="'.esc_url( admin_url("admin-ajax.php") ).'" method="post" id="email-verification">
                <p class="error">'.$error.'</p>
                <input type="radio" label="Купить доступ на 12 месяцев" value="purchase" name="rguroo_desired_action" checked>Купить доступ на 12 месяцев</input>
                <input type="radio" label="Продлить аккаунт" name="rguroo_desired_action" value="renewal">Продлить аккаунт</input>
                <input type="radio" label="Создать пробный аккаунт" name="rguroo_desired_action" value="trial">Создать пробный аккаунт</input>
                <p class="form-subtext">* обязательные поля</p>
                <p>Email адрес*</p>
                <input type="text" name="rguroo_email" required>
                <p>Повторите email адрес*</p>
                <input type="text" name="rguroo_email_confirmation" required>
                <input type="hidden" name="action" value="email_verification_form">
                <input type="submit" value="Отправить"> 
            </form>';
}

Что я знаю: проблема не в jQuery отправке post запроса (или по крайней мере в формировании запроса). При отправке jQuery отправляет post со всеми правильными параметрами. Я также знаю, что не использую разные nonce. Я пробовал размещать error_log() в разных местах callback функции, но ни один из них не появлялся в debug.log. Это наводит меня на мысль, что callback вообще не вызывается, но я не понимаю почему. Также, даже если я делаю тест, который должен завершиться ошибкой, jQuery все равно считает его успешным.

Я потратил весь день на эту форму и чувствую себя идиотом. Может кто-то с большим количеством мозговых клеток подскажет, где я ошибаюсь?

Огромное спасибо.

2
Комментарии

Вам не следует выводить php через echo, используйте wp_send_json для ответа обратно в javascript.

Nathan Powell Nathan Powell
20 июн. 2019 г. 00:24:46

@NathanPowell Я попытался изменить код, но он всё равно не работает. Я использовал это для ошибок: wp_send_json_error(array('error'=>'Email is not valid')); и у меня есть wp_send_json_success(); в конце. Стоит отметить, что я ввожу "test" и "test" в оба поля для email. Это означает, что ответ должен завершиться с ошибкой через wp_send_json_error(). Однако он всё равно успешно выполняется и выводит страницу в консоль

Eli Eli
20 июн. 2019 г. 00:37:23
Все ответы на вопрос 5
1

Вам нужно указать действие в вашем AJAX-запросе для вызова PHP-функции

url : ajax_info.ajax_url,
type : 'post',
data : form_data,
action: email_output_verification,
20 июн. 2019 г. 03:34:09
Комментарии

Это не то. Действие уже есть. Из формы: <input type="hidden" name="action" value="email_verification_form">, из javascript: var form_data = jQuery(this).serializeArray();. Оно включается при сериализации формы. Просто для проверки я использовал инструменты разработчика и посмотрел параметры, которые отправляются с моим POST-запросом. Как видно из этого скриншота, параметры правильно устанавливаются и отправляются

Eli Eli
20 июн. 2019 г. 07:46:33
1

Вызов этой функции дополняет функцию die() в PHP. Разница в том, что HTML будет отображен пользователю в случае стандартного веб-запроса

Взято из этого источника

Пробовали ли вы использовать die() вместо wp_die() или exit()?

20 июн. 2019 г. 10:37:12
Комментарии

Всё еще не работает. Кроме того, если бы callback работал правильно, мой тестовый сценарий провалился бы, что привело бы к отсутствию каких-либо сообщений в консоли. Другими словами, я не думаю, что выполнение вообще доходит до wp_die()

Eli Eli
20 июн. 2019 г. 12:28:20
0

Эта проблема возникает, когда имя PHP-файла в AJAX-запросе указано неверно.

Например:

$.post
(       
  'ajax.phpp',
  variables,
  [...]

Правильный вариант:

$.post
(       
  'ajax.php',
  variables,
  [...]
25 мар. 2020 г. 23:54:56
0

Проблема в вашем коде: некорректная работа AJAX хука и атрибута Form Action в шорткоде

Измените ваш код и протестируйте

Код приведен ниже

functions.php

 function enqueue_scripts() {
        // Подключаем CSS
        //wp_enqueue_style('wp-news-search', plugins_url('/css/wp-news-search.css', __FILE__));
        // Подключаем и локализуем JS
        wp_enqueue_script('ajax-script', get_template_directory_uri().'/js/wp-news-search_query.js', array('jquery'), null, true);
        wp_localize_script('ajax-script', 'ajax_info',
            array('ajax_url' => admin_url('admin-ajax.php'),
                'security' => wp_create_nonce('9pU0Pk7T01'),
            ));
 }

add_action( 'wp_ajax_no_email_verification_form', 'verify_and_sanitize_email_form' );
add_action( 'wp_ajax_email_verification_form', 'verify_and_sanitize_email_form' );

// Верификация email
function verify_and_sanitize_email_form() {
    // Проверяем реферер
   check_ajax_referer( '9pU0Pk7T01', 'security' );

   parse_str($_POST['data'], $data);
    
    if(empty($_POST) || !isset($data['rguroo_email']) || !isset($data['rguroo_email_confirmation']) || !isset($data['rguroo_desired_action'])) {
        echo 'Одно или несколько полей не заполнены';
        wp_die();
    }
    $sanitized_email = sanitize_email( esc_html($data['rguroo_email'] ));
    $sanitized_email_confirmation = sanitize_email( esc_html($data['rguroo_email_confirmation'] ));
    $desired_action = esc_html($data['rguroo_desired_action']);

    if(!is_email( $sanitized_email ) || !is_email( $sanitized_email_confirmation )) {
        echo 'Некорректный email';
        wp_die();
    }

    if($sanitized_email !== $sanitized_email_confirmation) {
        echo 'Email адреса не совпадают';
        wp_die();
    }

    if($desired_action !== 'purchase' || $desired_action !== 'renewal' || $desired_action !== 'trial') {
        echo 'Критическая ошибка с радио-кнопками';
        wp_die();
    }

    if(!isset($_COOKIE['rguroo_form_type'])) {
        echo 'Ошибка сервера';
        wp_die();
    }

    // Логика проверки студенческого email
    $form_type = $_COOKIE['rguroo_form_type'];
    if($form_type === 'student') {
        $trail = substr($sanitized_email, -4);
        if($trail !== '.edu') {
            echo 'Невалидный студенческий email';
            wp_die();
        }
        // Дополнительная логика для университетов
    }
    setcookie('rguroo_form_action',$desired_action, 14 * DAY_IN_SECONDS);
    setcookie('rguroo_form_email', $sanitized_email, 14 * DAY_IN_SECONDS);
    echo "success";
    wp_die();
}

add_shortcode('wp_news_search','wp_news_search_form');
 function wp_news_search_form() {
    return '<form id="email-verification">
            <p class="error">'.$error.'</p>
            <input type="radio" label="Купить 12-месячный доступ" value="purchase" name="rguroo_desired_action" checked>Купить 12-месячный доступ</input>
            <input type="radio" label="Продлить аккаунт" name="rguroo_desired_action" value="renewal">Продлить аккаунт</input>
            <input type="radio" label="Создать пробный аккаунт" name="rguroo_desired_action" value="trial">Создать пробный аккаунт</input>
            <p class="form-subtext">* обязательные поля</p>
            <p>Email адрес*</p>
            <input type="text" name="rguroo_email" required>
            <p>Подтвердите email адрес*</p>
            <input type="text" name="rguroo_email_confirmation" required>
            <input type="hidden" name="action" value="email_verification_form">
            <input type="submit" value="Отправить"> 
        </form>';
    }

Js

  jQuery(document).ready(function () {
  jQuery('#email-verification').submit(function (event) {
     event.preventDefault();
    var form_data = jQuery(this).serialize();
    jQuery.ajax({
          url : ajax_info.ajax_url,
          type : 'post',
          data: {
              action: 'email_verification_form',
              data: form_data,
              security: ajax_info.security
            },
          success : function( response ) {
              console.log(response);
              if(response !== 'success') {
                jQuery('p.error').html(response);
              } else {
                location.reload();
              }
          },
          fail : function( err ) {
              jQuery('.error').innerHTML = "Ошибка соединения с сервером";
          }
      });
    return false;
  });
});
1 янв. 2021 г. 10:46:13
0

Это может сработать. Найдите ваш div по имени класса из ответа и получите его innerHTML.

success : function( response ) {
              var error = $(response).find('.error-div')[0].innerHTML;
              if(response !== 'success') {
                jQuery('.error').innerHTML = error;
              }
3 мая 2021 г. 16:05:46