Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Супер Долгое выполнение скрипта (https://javascript.ru/forum/jquery/84966-super-dolgoe-vypolnenie-skripta.html)

BorisJe 18.02.2023 12:48

Супер Долгое выполнение скрипта
 
Всем привет ребята. Скрипт

(function($) {
	$(function() {
		
		jQuery('#quote_form').on('submit', function(e){
			e.preventDefault();
			jQuery('.btn ').attr('disabled','disabled');
			jQuery('#quote_form').addClass('form_sending');
			var request = {
				option       : 'com_ajax',
				module       : 'c_form',
				method       : 'sendMail',
				format       : 'row',	
				data: jQuery('#quote_form').serialize(),	
				src: window.location.href,
			};
			jQuery.ajax({
				method: 'POST', 
				data: request,
				
			})
			.success(function(response){
				console.log(response);
				//jQuery(location).attr('href', window.location.origin + '/thanks-you-for-contacting');
			});
		});
	}); 
})(jQuery);


<?php 
 
 
 
require_once '../../configuration.php'; 
 
$jconfig = new JConfig(); 
 
$host   = $jconfig->host; 
$dbname  = $jconfig->db; 
$username  = $jconfig->user; 
$password  = $jconfig->password; 
$dbprefix  = $jconfig->dbprefix; 
 
$db = mysqli_connect($host, $username, $password, $dbname); 
if (!$db) { 
    die('Ошибка соединения: ' . mysqli_error()); 
} 
$stmt = $db->prepare('SELECT params FROM ' . $dbprefix .'template_styles WHERE template = "easy_moving"'); 
$stmt->execute(); 
$result = $stmt->get_result(); 
$row = $result->fetch_assoc(); 
$params = json_decode($row['params']); 
mysqli_close($db); 
 
 
$to = $params->email; 
 
$subject = $_POST['subject'];  
$mailheaders = "Content-type:text/html;charset=utf-8rn";  
$mailheaders .= "From: SiteRobot <noreply@easy-moving.ca/>rn";  
$mailheaders .= "Reply-To: [email]noreply@easy-moving.ca[/email]/";  
 
if ($subject == 'Free Quote') { 
 $message = 
 '<table> 
  <tbody> 
   <tr> 
    <td>Moving From</td> 
    <td>'. $_POST['movingfrom'] .'</td> 
   </tr> 
   <tr> 
    <td>Moving To</td> 
    <td>'. $_POST['movingto'] .'</td> 
   </tr> 
   <tr> 
    <td>Contact Phone</td> 
    <td>'. $_POST['phone'] .'</td> 
   </tr> 
   <tr> 
    <td>Full Name</td> 
    <td>'. $_POST['fullname'] .'</td> 
   </tr> 
   <tr> 
    <td>Email Address</td> 
    <td>'. $_POST['email'] .'</td> 
   </tr> 
   <tr> 
    <td>Moving Date</td> 
    <td>'. $_POST['movingdate'] .'</td> 
   </tr> 
   <tr> 
    <td>What Size?</td> 
    <td>'. $_POST['whatsize'] .'</td> 
   </tr> 
   <tr> 
    <td>How did you hear about us?</td> 
    <td>'. $_POST['howdid'] .'</td> 
   </tr> 
  </tbody> 
 </table>'; 
} 
 
elseif ($subject == 'Free Estimate Online') { 
 $message = 
 '<table> 
  <tbody> 
   <tr> 
    <td>Full Name</td> 
    <td>'. $_POST['fullname'] .'</td> 
   </tr> 
   <tr> 
    <td>Email Address</td> 
    <td>'. $_POST['email'] .'</td> 
   </tr> 
   <tr> 
    <td>Contact Phone</td> 
    <td>'. $_POST['phone'] .'</td> 
   </tr> 
   <tr> 
    <td>Moving From</td> 
    <td>'. $_POST['movingfrom'] .'</td> 
   </tr> 
   <tr> 
    <td>Moving To</td> 
    <td>'. $_POST['movingto'] .'</td> 
   </tr> 
   <tr> 
    <td>Moving Date</td> 
    <td>'. $_POST['movingdate'] .'</td> 
   </tr> 
   <tr> 
    <td>Move Size</td> 
    <td>'. $_POST['movesize'] .'</td> 
   </tr> 
   <tr> 
    <td>Truck Size</td> 
    <td>'. $_POST['trucksize'] .'</td> 
   </tr> 
   <tr> 
    <td>Сomments</td> 
    <td>'. $_POST['comments'] .'</td> 
   </tr> 
  </tbody> 
 </table>'; 
} else { 
 die('error'); 
} 
 
 
 
$res = mail($to, $subject, $message, $mailheaders); 
echo $res; 
 
?>zz


Супер долго выполняется, Я уже не знаю что с ним делать.
А проблема в том что пока он выполняется пользователь еще раз 15 жмет на кнопку, думаю что не работает и по итогу приходит 9999 сообщений от пользователя, в зависимость от агрессии.

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

Ссылка https://easy-moving.ca/get-free-quote

voraa 18.02.2023 13:57

Ну так "размораживай", когда придет ответ от сервера.
Пока не ответил, показывай какой нибудь значок загрузки, что бы пользовал спокойней был.

BorisJe 18.02.2023 15:05

Цитата:

Сообщение от voraa (Сообщение 550738)
Ну так "размораживай", когда придет ответ от сервера.
Пока не ответил, показывай какой нибудь значок загрузки, что бы пользовал спокойней был.

Да поставил уже, Он крутится и крутится. Долго
Может конечно не в скрипте дело. Cms Joomla

BorisJe 18.02.2023 15:13

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

voraa 18.02.2023 17:46

Не получится. Нельзя послать запрос с одной страницы, а ответ получить на другой.
Тогда сначала делай редирект, и с той страницы посылай запрос.
Данные для запроса можно через localStorage передать.

Nexus 18.02.2023 17:53

Такие операции по-хорошему асинхронно выполнять нужно.
Самое простое - складируйте письма, которые нужно отправить в табличку в БД и по крону отправляйте небольшие порции раз в минуту.
Для пользователя такие запросы к серверу моментальными должны стать.

BorisJe 19.02.2023 03:09

Ну смотрите пользователю просто рыба отправляется. И все. Уведомление что получили, а админу уже форма. То есть админ должен получить форму а пользователю ответ что все хорошо.
Можно не редирект делать, а просто форму или сообщение что все ок.
Но Я что то вообще заглох. Даже понять не могу кому дольше отправляется, пользователю или админу

BorisJe 19.02.2023 06:46

Мне кажется через базу данных не получится. Плюс ещё надо будет какой то признак ставить что отправилось или удалять вообще.
А можно как нибудь асинхронно запустить. Пользователю показать страницу что все ок. А дальше все просто само отрабатывает. Результат успеха не важен.
Пользователь заполнил форму, ему сразу же страница типа все ок. А дальше идёт уже отправка. Не важен в общем успешный результат или нет

BorisJe 19.02.2023 08:50

Если не ок то пользователь вообще ничего не видет. А так пока для личного спокойствия, сразу показать пользователю страницу редиректа и не ждать ответа от сервера. Так можно сделать?

voraa 19.02.2023 10:34

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

Белый шум 19.02.2023 20:29

Цитата:

Сообщение от BorisJe
Пользователю показать страницу что все ок. А дальше все просто само отрабатывает. Результат успеха не важен.

https://dron.by/post/kak-zakryt-soed...e-skripta.html

В начале скрипта поставить код с этой страницы (первые 20 строк), заменив 7-ю строку на echo "Ok";
И убрать строку echo $res; в конце вашего скрипта.

BorisJe 20.02.2023 09:16

Цитата:

Сообщение от Белый шум (Сообщение 550774)
https://dron.by/post/kak-zakryt-soed...e-skripta.html

В начале скрипта поставить код с этой страницы (первые 20 строк), заменив 7-ю строку на echo "Ok";
И убрать строку echo $res; в конце вашего скрипта.

Спасибо за объяснение и код
Не приходят формы на почту админу, и так и так попробовал

Белый шум 20.02.2023 13:14

Цитата:

Сообщение от BorisJe
Не приходят формы на почту админу, и так и так попробовал

Вот тут пишут - https://bugs.php.net/bug.php?id=60586#1639418517 - что ignore_user_abort(true); не работает для FastCGI в связке с IIS, а возможно и с другими серверами тоже.

Значит я вижу три выхода:
- либо менять протокол взаимодействия с веб-сервером и/или сам веб-сервер;
- либо ставить локально почтовый сервер (для быстрого приёма письма), который будет затем перенаправлять почту куда надо;
- либо вариант, который предложил Nexus.

BorisJe 20.02.2023 13:46

Цитата:

Сообщение от Белый шум (Сообщение 550780)
Вот тут пишут - https://bugs.php.net/bug.php?id=60586#1639418517 - что ignore_user_abort(true); не работает для FastCGI в связке с IIS, а возможно и с другими серверами тоже.

Значит я вижу три выхода:
- либо менять протокол взаимодействия с веб-сервером и/или сам веб-сервер;
- либо ставить локально почтовый сервер (для быстрого приёма письма), который будет затем перенаправлять почту куда надо;
- либо вариант, который предложил Nexus.


сейчас в Joomla стоит phpMail, когда настраивал smtp вообще не приходило

Белый шум 20.02.2023 14:08

Цитата:

Сообщение от BorisJe
сейчас в Joomla стоит phpMail, когда настраивал smtp вообще не приходило

Это не имеет значения. Под локальным почтовым сервером я имел ввиду postfix или exim, либо другой MTA. Его настройка в такой роли нетривиальна, так что придётся заплатить кому-нибудь знающему. Пэтому лучше выбрать что-то из оставшихся двух вариантов.

BorisJe 20.02.2023 15:04

А что если: сервак должен получать запрос, запускать в отдельном потоке отправку письма, и отвечать клиенту что всё ок
т.е. фронт отправить запрос и получит ответ за секунду.
А письмо отправлять сервер будет уже столько сколько надо
т.е. фронт должен дождаться ответа что запрос на сервер отправлен после чего сделать редирект

пхп работает с потоками?

Белый шум 20.02.2023 17:28

По потокам не подскажу, но можно ещё запустить внешний фоновый процесс через exec и его аналоги:
https://php.ru/forum/threads/zapusk-...9/#post-489196
https://stackoverflow.com/questions/...nswer-14556052
https://ru.stackoverflow.com/questio...BD%D0%B8%D1%8F

Тут ключевое слово - фоновый. Иначе основной скрипт будет ждать завершения дочернего процесса.

Как вариант, можно так запускать не напрямую консольный php-скрипт, а дёргать УРЛ через curl или wget:
exec("wget -b -o /dev/null 'https://javascript.ru/?s=subject&text=some text для примера'");
^^тут часть >/dev/null & не нужна, т.к. мы указали ключ -b для wget, благодаря чему он сам переходит в фон; а ключом -o мы сказали что и вывод с этой страницы сохранять не нужно.

Nexus 20.02.2023 17:58

Цитата:

Сообщение от BorisJe
А что если: сервак должен получать запрос, запускать в отдельном потоке отправку письма, и отвечать клиенту что всё ок
т.е. фронт отправить запрос и получит ответ за секунду.
А письмо отправлять сервер будет уже столько сколько надо
т.е. фронт должен дождаться ответа что запрос на сервер отправлен после чего сделать редирект

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

Попробуйте просто отправить ответ пользователю, что "все хорошо" и продолжайте выполнять отправку сообщений:
https://gist.github.com/bubba-h57/32593b2b970366d24be7
https://stackoverflow.com/questions/...nnection-early

Цитата:

Сообщение от BorisJe
пхп работает с потоками?

Да, работает, но я не уверен, что поток останется "жив" после завершения работы его "родителя".

Белый шум 20.02.2023 18:22

Цитата:

Сообщение от Nexus
Попробуйте просто отправить ответ пользователю, что "все хорошо" и продолжайте выполнять отправку сообщений:

У него не работает ignore_user_abort(true); - скрипт завершается при отключении клиента. Багрепорт - https://bugs.php.net/bug.php?id=60586#1639418517

BorisJe 23.02.2023 19:43

а что если так?
$(document).ready(function(){
			$('.quote_form').click(function(){
			  // get text field value
			  var userName = $('.myField').val();
			  var emailAddress = 'myemail@server.com';
			  // ajax request and response in function
			  var jqxhr = $.ajax({
				url: 'sendMail.php', 
				type: 'POST',
				data: jQuery('#quote_form').serialize(),
				src: window.location.href,
				success:function(responseAnyNameHere) {
				  $('.responseArea').html(responseAnyNameHere);
				},
				statusCode:{
				  404:function(){
					//$('.error').html("Page not found!");
					alert( "file not found" );
				  }
				}
			  }).done(function() {
			  alert( "success" );
			  }).fail(function() {
			  alert( "error" );
			  }).always(function() {
			  alert( "complete" );
			});
		}}));


Только где то ошибка

BorisJe 23.02.2023 20:13

$(document).ready(() => {
			$('#quote_form').on('submit', function () {
				jQuery('#quote_form').addClass('form_sending');
				$.ajax({
					url: "/templates/easy_moving/sendmail.php",
					method: "POST",
					data: jQuery('#quote_form').serialize(),
					contentType: false,
					cache: false,
					processData: false,
					src: window.location.href,
					success: function (data) {
						console.log(data);
					}
				});
			});
		});


Ошибок нет, и не работает

BorisJe 23.02.2023 21:09

$('#quote_form').click(function(){
			$.post(
				'sendmail.php', // адрес обработчика
				 $("#quote_form").serialize(), // отправляемые данные  		
				
				function(msg) { // получен ответ сервера  
				}
			);
		});


Тоже не пошло

Белый шум 23.02.2023 22:01

BorisJe,
чем это отличается от изначального варианта?

BorisJe 23.02.2023 22:09

$.ajax({
            url: 'process.php', 
            type: 'POST',
            data: 'passVarOne='+userName+'&passVarTwo='+emailAddress,
            success:function(responseAnyNameHere) {
              $('.responseArea').html(responseAnyNameHere);
            },
            statusCode:{
              404:function(){
                //$('.error').html("Page not found!");
                alert( "file not found" );
              }
            }
          }).done(function() {
          alert( "success" );
          }).fail(function() {
          alert( "error" );
          }).always(function() {
          alert( "complete" );
        });


Вот еще нашел код. Идея такая выполнить, прыгнуть в always и сделать редирект. Работает еще до fail

Белый шум 23.02.2023 23:05

BorisJe,
Это не поможет. При редиректе произойдёт отключение от серверного скрипта и тот завершится, не успев ничего отправить.

Если не можете решить проблему на стороне сервера, то замените крутилку на прогресс-бар, рассчитанный на 15 секунд, плюс текст с извинениями и просьбой подождать это время. В идеале - ещё занять/развлечь чем-нибудь на это время: текстом, картинкой, и т.д.

BorisJe 24.02.2023 14:49

Цитата:

Сообщение от Белый шум (Сообщение 550869)
BorisJe,
Это не поможет. При редиректе произойдёт отключение от серверного скрипта и тот завершится, не успев ничего отправить.

Если не можете решить проблему на стороне сервера, то замените крутилку на прогресс-бар, рассчитанный на 15 секунд, плюс текст с извинениями и просьбой подождать это время. В идеале - ещё занять/развлечь чем-нибудь на это время: текстом, картинкой, и т.д.

Тогда Мне кажется с первоначальным скриптом что то не так, он даже выключенной отправкой работает долго. Там используется Jquery 1.12.Х

На 3.6 Делается по другому, но и быстрее работает.

что сделал

$(document).ready(() => {
			$('#quote_form').on('submit', function () {
				jQuery('#quote_form').addClass('form_sending');
				$.ajax({
					url: "/templates/easy_moving/sendmail.php",
					method: "POST",
					data: jQuery('#quote_form').serialize(),
					contentType: false,
					cache: false,
					processData: false,
					src: window.location.href,
					success: function (data) {
						console.log(data);
					}
				});
			});
		});


На отправку не идет. почемуто

Rise 24.02.2023 15:04

BorisJe,
Что вы делаете? Почитайте документацию $.ajax(), cache работает только с GET и HEAD, а src там нет.

Как вы работоспособность проверяете? Откройте консоль (F12), посмотрите ошибки.

BorisJe 24.02.2023 18:13

Цитата:

Сообщение от Rise (Сообщение 550875)
BorisJe,
Что вы делаете? Почитайте документацию $.ajax(), cache работает только с GET и HEAD, а src там нет.

Как вы работоспособность проверяете? Откройте консоль (F12), посмотрите ошибки.

$(document).ready(() => {
		$(function() {
			$('quote_form').submit(function(e) {
			  $.ajax({
				url: '/templates/easy_moving/sendmail.php',
				data: $("#quote_form").serialize(),
			  }).done(function() {
				console.log('success');
			  }).fail(function() {
				console.log('fail');
			  });
			  //отмена действия по умолчанию для кнопки submit
			  e.preventDefault(); 
			});
		  });
		});


Захожу во все кроме Done

Rise 25.02.2023 01:03

BorisJe,
Так ошибка то какая в консоли что пишет?

BorisJe 25.02.2023 02:27

Цитата:

Сообщение от Rise (Сообщение 550884)
BorisJe,
Так ошибка то какая в консоли что пишет?

аллерты Мои выскакивают, ошибок нет

Rise 25.02.2023 09:44

BorisJe,
А так?
.fail(function(jqXHR, textStatus, errorThrown) {
    console.log('fail: ', textStatus, errorThrown);
})

BorisJe 25.02.2023 16:02

Цитата:

Сообщение от Rise (Сообщение 550892)
BorisJe,
А так?
.fail(function(jqXHR, textStatus, errorThrown) {
    console.log('fail: ', textStatus, errorThrown);
})

fail:  error Internal Server Error

BorisJe 25.02.2023 16:14

$(document).ready(() => {
    $(function() {
        $('#quote_form').submit(function(e) {
    $.ajax({
        url: 'sendmail.php', 
        type: 'POST',
        data: $("#quote_form").serialize(),
        success:function(responseAnyNameHere) {
          $('.responseArea').html(responseAnyNameHere);
        },
        statusCode:{
          404:function(){
            //$('.error').html("Page not found!");
            alert( "file not found" );
          }
        }
      }).done(function() {
      alert( "success" )
      }).fail(function(jqXHR, textStatus, errorThrown) {
console.log('fail: ', textStatus, errorThrown);
})
.always(function() {
      alert( "complete" );
    });
          //отмена действия по умолчанию для кнопки submit
          e.preventDefault(); 
        });
      });
    });


Ошибок нет, везде успех но и не отправилось. Но отработало быстро

BorisJe 26.02.2023 11:54

Я уже склоняюсь к тому что дело не в отправки а в самом скрипте JS.
Подскажите пожалуйста ребята, что Я не так делаю? Сейчас и ошибок нет и не отправился

Rise 26.02.2023 15:39

BorisJe,
Надо действовать последовательно, а не писать рандомный код каждый пост. Зачем в посте #28 приводить код без POST, если в посте #1 с POST... Но даже без POST, судя по ошибке "Internal Server Error", с вашим сервером что-то не так, а может со скриптом... JS PHP.

Также непонятно что вы под "не отправился" имеете ввиду, в вашем случае отправить можно ajax из js, а можно mail из php... хз кого у вас там не отправляется и как вы это определяете...

BorisJe 27.02.2023 13:02

Цитата:

Сообщение от Rise (Сообщение 550910)
BorisJe,
Надо действовать последовательно, а не писать рандомный код каждый пост. Зачем в посте #28 приводить код без POST, если в посте #1 с POST... Но даже без POST, судя по ошибке "Internal Server Error", с вашим сервером что-то не так, а может со скриптом... JS PHP.

Также непонятно что вы под "не отправился" имеете ввиду, в вашем случае отправить можно ajax из js, а можно mail из php... хз кого у вас там не отправляется и как вы это определяете...

Да, извините. Спасибо за замечания. Они все по делу. Я просто немного что разошелся


ПХП скрипт работает правильно. Лучше там уже не сделать
А вот Js какой то странный.

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

Rise 27.02.2023 20:12

Цитата:

Сообщение от BorisJe
ПХП скрипт работает правильно

Цитата:

Сообщение от BorisJe
почту не отправляет

Это как? Правильно не отправляет почту...

BorisJe 28.02.2023 11:59

Цитата:

Сообщение от Rise (Сообщение 550925)
Это как? Правильно не отправляет почту...

Ну при старом варианте, пхп отрабатывает. Я уверен что проблема в Моем последнем js скрипте


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