Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Не могу передать данные из формы в php (https://javascript.ru/forum/dom-window/75605-ne-mogu-peredat-dannye-iz-formy-v-php.html)

Chmil 24.10.2018 01:32

Не могу передать данные из формы в php
 
Здравствуйте уважаемые, не получается решить простую задачу, мне нужно передать данные полей html-формы в php-скрипт, там обработать и вернуть новые значения. Нужно чтобы страница не перегружалась. Приложение (онлайн конвертер) делаю как плагин для вордпреса, два файла js и php находятся в одной папке. Форма на страницу добавляется шорткодом. У меня кое-что получилось, но скрипт не хочет передавать данные ни в какую, поэтому прошу вашей помощи, ниже код:
Часть php-файла:
//получаем ссылку на файл для html-формы
function request_url()
{
  $result = ''; // Пока результат пуст
  $default_port = 80; // Порт по-умолчанию
 
  // А не в защищенном-ли мы соединении?
  if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS']=='on')) {
    // В защищенном! Добавим протокол...
    $result .= 'https://';
    // ...и переназначим значение порта по-умолчанию
    $default_port = 443;
  } else {
    // Обычное соединение, обычный протокол
    $result .= 'http://';
  }
  // Имя сервера, напр. site.com или www.site.com
  $result .= $_SERVER['SERVER_NAME'];
 
  // А порт у нас по-умолчанию?
  if ($_SERVER['SERVER_PORT'] != $default_port) {
    // Если нет, то добавим порт в URL
    $result .= ':'.$_SERVER['SERVER_PORT'];
  }
  // Последняя часть запроса (путь и GET-параметры).
  $result .= $_SERVER['REQUEST_URI'];
  // Уфф, вроде получилось!
  return $result;
}

add_shortcode('lbkggetfishbychmil', 'lb_kg_getfish');

function lb_kg_getfish($atts) {
 wp_enqueue_script('lb-kg-script', plugins_url('lb-kg.js', __FILE__), array('jquery'));
 wp_enqueue_style('lb-kg-styles', plugins_url('style.css', __FILE__));
 echo '<div class="form-lb-kg">';
 echo '<form action="' . request_url() . '" method="POST" id="lbkg_form">';
 echo '<fieldset>';
 echo '<legend>Онлайн конвертер (фунты & килограммы)</legend>';
 echo '<p><input type="kg" id="kg" placeholder="кг"></p>';
 echo '<p><input type="lb" id="lb" placeholder="lb"></p>';
 echo '<input id="btn_submit" type="button" value="Посчитать" />';
 echo '</fieldset>';
 echo '</form>';
 echo '<div class="messages"></div>';
 echo '</div>';
}

if (isset($_POST["kg"])) {	
	
	$arr = array('result' => '123456789');
	
	echo json_encode($arr);
	
}

Файл javascript:
jQuery(document).ready(function($){
			$('#btn_submit').click(function(){
				//берем из формы метод передачи данных
				var m_method=$('#lbkg_form').attr('method');
				//получаем адрес скрипта на сервере, куда нужно отправить форму
				var m_action=$('#lbkg_form').attr('action');
				// отправляем данные
				$.ajax({
					type: m_method,
					url: m_action,
					dataType: "json", // тип передачи данных
					data: $("lbkg_form").serialize(),
					// после получения ответа сервера
					success: function(data){
						$('.messages').html(data.result); // выводим ответ сервера
					}
				});
			});
		});


Прошу помочь разобраться, спасибо

laimas 24.10.2018 02:01

$('#btn_submit').click(function(){ - заменить на

$('#lbkg_form').submit(function(e) {
    e.preventDefault();
    $.ajax({
        type: this.method,
        url: this.action,
        dataType: "json", // тип передачи данных - это тип ожидаемых данных от сервера
        data: $(this).serialize(),
        .....

Chmil 24.10.2018 19:01

laimas,
спасибо за ответ, изменил как Вы указали, но увы данные не передаются((( не работает

laimas 24.10.2018 19:17

Значит не принимаете их должным образом или иные косяки допускаете.

PS. Если асинхронный запрос производится к тому же файлу, что порождает форму, то прием этого запроса должен быть самым первым в структуре кода. Так как показано:

вывод формы
затем

if (isset($_POST["kg"])) {

$arr = array('result' => '123456789');

echo json_encode($arr);

}

это ошибка, не должно быть до и после ответа в формате json никаких выводов в браузер. Меняйте структуру кода.

Chmil 24.10.2018 19:24

выше в коде описано как я проверяю наличие переменной, вот повторю:
if (isset($_POST["kg"])) {	
	
	$arr = array('result' => '123456789');
	
	echo json_encode($arr);
	
}

SuperZen 24.10.2018 19:29

надо посмотреть в консоле разработчика, в разделе "сеть", что отправилось, и что принялось.

Chmil 24.10.2018 22:31

в консоли нечего не передается, пробовал и на локальном пк (open server) и на хостинге, вот загрузил на хостинг http://muz-bar.ru/zemfira-poobeshhal...vyj-albom.html

в исходном коде подключается правильно, после jQuery
<script type='text/javascript' src='http://muz-bar.ru/wp-includes/js/jquery/jquery.js?ver=1.12.4'></script>
<script type='text/javascript' src='http://muz-bar.ru/wp-includes/js/jquery/jquery-migrate.min.js?ver=1.4.1'></script>
<script type='text/javascript' src='http://muz-bar.ru/wp-content/plugins/lb-kg/lb-kg.js?ver=4.9.8'></script>

laimas 24.10.2018 23:25

Цитата:

Сообщение от Chmil
выше в коде описано как я проверяю наличие переменной

Нельзя так проверить передачу в json формате, ибо клиент в вашем случае JSON не получает! А JQ его явно ожидает, что вы ему предписали, и не получив из ответа json, вернет в success пустую data. Если вы не проанализируете другие параметры функции success, то даже знать не будете, что произошла ошибка.

Выбрасывайте из своего кода строки с 1 по 32, что это, зачем, в общем пока эта абракадабра не нужна. Будем считать, что далее в коде будет нормальный вызов функции lb_kg_getfish и клиент получит форму. Если вы проверяете получение формы тут же, то значит и запрос клиента к этому файлу. В этом случае структура кода на сервере может быть только такой для JSON (для запроса самой себя она всегда должна быть такой, а для json тем более):

if($_POST) { //можно проверить действительно ли асинхронный запрос и т.п.
ответ клиенту и обязательный exit
}

далее код обрабатывающий GET запрос - формирование страницы и вывод ее, собственно форма.

Ищите у себя косяки, ибо если я простой тестовый код со структурой описанной напишу, то он будет работать на все 100.

laimas 24.10.2018 23:46

А на клиенте запроса вообще нет, хотя обработчик установлен.

Chmil 25.10.2018 01:07

немного поправил код (ниже выкладываю полностью 2 файла), но он также не рабочий (((. В JS я не силен, поэтому обратился к Вам за помощью и исходя из выше изложенного есть вопросы, заранее извините если они слишком элементарны:

Цитата:

Нельзя так проверить передачу в json формате, ибо клиент в вашем случае JSON не получает!
почему нельзя проверить переменную на существование и если она существует выполнить определенный код?

$arr = array('result' => '123456789');
echo json_encode($arr);

ето не формирование JSON ответа?

Цитата:

Если вы не проанализируете другие параметры функции success
я думал что ето масив $arr = array('result' => '123456789'); и он же и есть ответ клиенту

строка add_shortcode('lbkggetfishbychmil', 'lb_kg_getfish'); добавляет шорткод - lbkggetfishbychmil, который потом используется для вставки формы и ответа в запись.

Цитата:

ответ клиенту и обязательный exit
зачем exit?

Цитата:

далее код обрабатывающий GET запрос
для чего? я ж не использую GET запросы

Ниже выкладываю 2 файла полностью, они размещены в папке плагинов wordpress - /wp-content/plugins/lb-kg/ . Для вызова формы в самой записи, например как тут http://muz-bar.ru/zemfira-poobeshhal...vyj-albom.html нужно сначала в админке вордпрес активировать данный плагин, а потом во время редактирования записи вставить в нее шорткод в таком формате [lbkggetfishbychmil]. Все работает кроме скрипта отправки данных полей формы на JS.

php-файл:
<?php
/*
* Plugin Name: Lb & Kg
* Description: Перевод веса фунтов в килограммы и наоборот
* Author: Chmil
* Version: 1.0
*/

add_shortcode('lbkggetfishbychmil', 'lb_kg_getfish');

function lb_kg_getfish($atts) {
 wp_enqueue_script('lb-kg-script', plugins_url('lb-kg.js', __FILE__), array('jquery'));
 wp_enqueue_style('lb-kg-styles', plugins_url('style.css', __FILE__));
 echo '<div class="form-lb-kg">';
 echo '<form action="' . plugins_url('lb-kg/lb-kg.php') . '" method="POST" id="lbkg_form">';
 echo '<fieldset>';
 echo '<legend>Онлайн конвертер (фунты & килограммы)</legend>';
 echo '<p><input type="kg" id="kg" placeholder="кг"></p>';
 echo '<p><input type="lb" id="lb" placeholder="lb"></p>';
 echo '<input id="btn_submit" type="button" value="Посчитать" />';
 echo '</fieldset>';
 echo '</form>';
 echo '<div class="messages"></div>';
 echo '</div>';
}

if (isset($_POST["kg"])) {
	
//добавил чтобы увидеть передаются ли данные
	$file = "text.txt";
if (!file_exists($file)) {
    $fp = fopen($file, "w"); 
    fwrite($fp, $_POST["kg"]);
    fclose($fp);
}
	
	$arr = array('result' => '123456789');
	
	echo json_encode($arr);
	
}

?>


js-файл:
jQuery(document).ready(function($){
			$('#lbkg_form').submit(function(e) {
				e.preventDefault();
				$.ajax({
					type: this.method,
					url: this.action,
					dataType: "json", // тип передачи данных - это тип ожидаемых данных от сервера
					data: $(this).serialize(),
					// после получения ответа сервера
					success: function(data){
						$('.messages').html(data.result); // выводим ответ сервера
					}
				});
			});
		});

laimas 25.10.2018 01:35

Цитата:

Сообщение от Chmil
ето не формирование JSON ответа?

JSON, но

Цитата:

Сообщение от Chmil
зачем exit?
для чего? я ж не использую GET запросы

если перед выводом в браузер json строки до этого вывода или после него будет также вывод в браузер, то клиент получит невалидный json. Как при этом поступит JQ написано выше.

Ваша страница ведь формируется не этим куском кода, а как мне не ведомо. Но по коду я могу только предполагать, что запрос (action формы) как-то связан с выводом в браузер (тут код формы и т.п.). Если это так, то обработчик запроса клиента должен быть первым в коде и завершается выходом, чтобы код следуемый далее и связанный с выводом не исполнялся.

Если запрос не связан с другими выводами и единственный вывод в нем, это вывод json, то все нормально.

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

laimas 25.10.2018 01:38

На клиенте есть установленный обработчик, но нет запроса. Это могут быть конфликты или что-то мешает и т.п. Для начала заремируйте подключение сторонних скриптов - метрику яшки и прочую лабуду, она пока не нужна, иначе в отладчике ... Проверить сам обработчик можно добавлением в его код вывод чего угодно в консоль, если он будет, то проблемы с самим методом $.ajax.

Chmil 25.10.2018 21:02

Цитата:

заремируйте подключение сторонних скриптов
на локалхосте нет ничего стороннего, там просто установлен вордпрес с дефолтной темой, там должно работать, но не работает

Цитата:

Проверить сам обработчик можно добавлением в его код вывод чего угодно в консоль
ето можно сделать в браузере в инспекторе (F12)?

Цитата:

проблемы с самим методом $.ajax
скорее всего так и есть, даже не с методом а с спецификой взаимодействия с вордпрес

laimas 26.10.2018 03:30

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

Просто в обработчик отправления формы добавить строку: console.log(1) (до $.ajax), если в консоли отладчика будет вывод 1, значит нет иных кто бы мешал отправлению формы и проблема с $.ajax. В WP нет специфики взаимодействия, есть правила подключения плагинов и своих скриптов, что описано в документации WP. Их немного меняют от версии к версии, но все это отражается в доках. Собственно такой порядок не только в WP, но и в других CMS.

Интересно, а зачем на сервер отправлять запрос для перересчета каких-то килограммов, очень мощная математика? )

Chmil 26.10.2018 10:44

Цитата:

в обработчик отправления формы добавить строку: console.log(1) (до $.ajax)
с етим понял, вечером попробую

Цитата:

зачем на сервер отправлять запрос для перересчета каких-то килограммов, очень мощная математика?
не мощная, просто в JS я очень слабо разбираюсь, по этому делаю как я занаю, и как мне проще, по сути мне нужен простой конвертер, он может быть на чем угодно, главное чтобы работал, большое спасибо Вам за помощь

laimas 26.10.2018 11:57

Цитата:

Сообщение от Chmil
по сути мне нужен простой конвертер, он может быть на чем угодно

Ну так сама математика конвертирования не меняется от языка к языку, и не так сложно ее описать и на JS.
Если бы сервер по цвету глаз вычислял, что нужно самую малость и будет счастье, тогда бы был смысл прятать этот чудодейственный расчет на сервере. А простой конвертор, тут не выгодно обслуживать запросы и соединения, это должно быть сервисом на клиенте. С этого вопроса и нужно было начинать.

SuperZen 26.10.2018 12:26

jQuery(document).ready(function($){
       $('#btn_submit').click(function(){

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

Я уже намекал, что надо открыть консоль разработчика, и там смотреть результаты "клика", надо в саму ф-цию клика поставить что-нибудь типа console.log('clicked'), что бы убедиться что слушатель установлен и отрабатывает.

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

Chmil 27.10.2018 23:03

Цитата:

в обработчик отправления формы добавить строку: console.log(1) (до $.ajax)
сделал, и вот что получается, следующий код в консоль выводит информацию:
jQuery(document).ready(function($){
	console.log(1);
			$('#lbkg_form').submit(function(e) {				
				e.preventDefault();
				$.ajax({
					type: this.method,
					url: this.action,
					dataType: "json", // тип передачи данных - это тип ожидаемых данных от сервера
					data: $(this).serialize(),
					// после получения ответа сервера
					success: function(data){
						$('.messages').html(data.result); // выводим ответ сервера
					}
				});
			});
		});


а вот если пишу так:
jQuery(document).ready(function($){	
			$('#lbkg_form').submit(function(e) {	
			console.log(1);
				e.preventDefault();
				$.ajax({
					type: this.method,
					url: this.action,
					dataType: "json", // тип передачи данных - это тип ожидаемых данных от сервера
					data: $(this).serialize(),
					// после получения ответа сервера
					success: function(data){
						$('.messages').html(data.result); // выводим ответ сервера
					}
				});
			});
		});

то не работает, вот где запинание:
$('#lbkg_form').submit(function(e) {


возможно действительно
Цитата:

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

Цитата:

не так сложно ее описать и на JS
да, попробую сейчас написать калькулятор на js, как говорится гугл мне в помощь, но все-же мне бы хотелось решить вопрос отправки данных из полей формы аяксом, так сказать на будущее...

laimas 28.10.2018 03:11

У полей формы нет типов kg и lb, это удалить как мусор. А вот имена этим полям нужно определить - name="kg", name="lb", иначе на сервер такие поля не передаются по умолчанию. Кнопка отправления формы должна быть либо type="submit", либо <button>Посчитать</button>, и все будет работать.

Chmil 28.10.2018 12:28

сделал как Вы описали, теперь по нажатию на кнопку "Посчитать" информация в консоль выводится, но на сервер по прежнему данные не передаются, теперь получается проблема с самим методом ajax:
jQuery(document).ready(function($){	
			$('#lbkg_form').submit(function(e) {
				console.log(1);				
				e.preventDefault();
				$.ajax({
					type: this.method,
					url: this.action,
					dataType: "json", // тип передачи данных - это тип ожидаемых данных от сервера
					data: $(this).serialize(),
					// после получения ответа сервера
					success: function(data){
						$('.messages').html(data.result); // выводим ответ сервера
					}
				});
			});
		});


<?php
/*
* Plugin Name: Lb & Kg
* Description: Перевод веса фунтов в килограммы и наоборот
* Author: Chmil
* Version: 1.0
*/

if (isset($_POST["kg"])) {
	
	//добавил для проверки
	header('Location: http://www.google.com/');
	
	$arr = array('result' => '123456789');
	
	echo json_encode($arr);
	
}

add_shortcode('lbkggetfishbychmil', 'lb_kg_getfish');

function lb_kg_getfish($atts) {
 wp_enqueue_script('lb-kg-script', plugins_url('lb-kg.js', __FILE__), array('jquery'));
 wp_enqueue_style('lb-kg-styles', plugins_url('style.css', __FILE__));
 echo '<div class="form-lb-kg">';
 echo '<form action="' . plugins_url('lb-kg/lb-kg.php') . '" method="POST" id="lbkg_form">';
 echo '<fieldset>';
 echo '<legend>Онлайн конвертер (фунты & килограммы)</legend>';
 echo '<p><input name="kg" id="kg" placeholder="кг"></p>';
 echo '<p><input name="lb" id="lb" placeholder="lb"></p>';
 echo '<input id="btn_submit" type="submit" value="Посчитать" />';
 echo '</fieldset>';
 echo '</form>';
 echo '<div class="messages"></div>';
 echo '</div>';
}

?>

laimas 28.10.2018 13:03

id="kg", id="lb" для чего? Не увлекайтесь id, это не является обязательным условием, в данном случае они совсем не нужны и кроме как загрузка лишних байт клиентом ничего не дает. Можно кнопке отправке дать id, для того чтобы обратиться к ней до запроса, сделав ее недоступной, и доступной после завершения запроса. Хотя есть и другие способы, которые позволяют получить эту кнопку без всяких id, она между прочим доступна уже в событии произошедшем.

Никаких ошибок в Ajax нет, и код должен работать, смотреть ответ сервера в отладчике. Но проверять асинхронный запрос посредством перенаправления header('Location: http://www.google.com/'); это глупость, ответ приходит в контейнер, никакого перенаправления не увидеть, и это чужой домен. Ну и уже не раз говорилось, что предписано получать json, а вы пытаетесь таким образом впарить клиенту иное, как поступит JQ уже говорилось. И если в РНР:

прием формы и ответ json как echo ...
далее код ...

это предпосылка к ошибке, ибо файл может завершаться выводом в браузер - пробелы, переносы ..., а это уже не json. Только exit(json_encode(array)), пора это усвоить.

Chmil 28.10.2018 14:22

laimas,
спасибо огромное, заработало, теперь чуть больше начал понимать как выполнять процес отладки приложений, проблема еще была в другом, в файл плагина необходимо было добавить строку
require($_SERVER['DOCUMENT_ROOT'].'/wp-load.php');


Цитата:

exit(json_encode(array))
Вы имеете ввиду что мой ответ сервера нужно переделать? например так?
$arr = array('result' => '123456789');
exit(json_encode($arr));

laimas 28.10.2018 14:31

Цитата:

Сообщение от Chmil
Вы имеете ввиду что мой ответ сервера нужно переделать?

Просто нужно запомнить, если данные это json, то любой вывод в браузер до и после вывода json запрещается. Поэтому нужно заканчивать работу скрипта после передачи json, если после него есть еще код или неконтролируемый вывод. И после передачи заголовка перенаправления также рекомендуется делать выход. А дабы исключить неконтролируемый вывод в браузер разработчики рекомендуют не закрывать закрывающим тегом ?> php-код.


Часовой пояс GMT +3, время: 03:24.