1

I have the following Javascript code

sendBtn.onclick = ()=> {
  inputField.focus();
  let xhr = new XMLHttpRequest();
  xhr.open("POST", "processes/chat.php", true);
  xhr.onload = ()=> {
    if(xhr.readyState === XMLHttpRequest.DONE) {
      if(xhr.status === 200) {
        inputField.value = "";
        $('html,body').animate({scrollTop: document.body.scrollHeight},"fast");
      }
    }
  }
  let formData = new FormData(form);
  xhr.send(formData);
}

And the following related code in chat.php (made minimal)

$stmt = $pdo->prepare("INSERT INTO messages(incoming_msg_id, outgoing_msg_id, msg)VALUES(:imsg, :omsg, :msg)");
$stmt-> bindValue(':imsg', $imsg);
$stmt-> bindValue(':omsg', sessionUser());
$stmt-> bindValue(':msg', encrypt($chatMsg, ENCRYPTION_KEY));
$stmt-> execute();

if($stmt){
  $sub = 'MAIL SUBJECT GOES HERE';
  $message = 'MAIL CONTENT GOES HERE';
  mailSender($sub, $message, "abc@gmail.com"); // SEND EMAIL (Uses PHPMailer)
}

As you can see I am inserting data in into the table and if inserted I am sending a mail to the relevant user. Everything is working fine. Mail is delivering perfectly too. The problem is the wait time. Until and unless the mail is successfully delivered, i.e., successful execution of mailSender() function above, I do not get response. Other ajax requests that are to be executed right after the given ajax request above are delayed. If I comment out the mailSender() function then everything works normally as required because the time taken to send the mail is nulled out. But while sending the email the ajax slows down waiting for the email to be sent and doesn't respond until the mail is sent / delivered.

Here is another ajax code that is related to the ajax code mentioned above. This code is responsible for "instantly" retrieving the data as soon as the data was inserted using the ajax code mentioned above. This code should work instantly but in the current scenario doesn't work unless the PHP code above successfully sends the mail, i.e., unless the mainSender() function has completed it's execution.

let takeDown = true;
setInterval(() => {
  var dataString = {incoming_id: incoming_id};
  let xhr = new XMLHttpRequest();
  xhr.open("POST", "processes/get-chat.php", true);
  xhr.onload = ()=> {
    if(xhr.readyState === XMLHttpRequest.DONE) {
      if(xhr.status === 200) {
        let data = xhr.response;
        chatBox.innerHTML = data.html;
        document.getElementById('theStatus').innerHTML = data.status;
        document.getElementById('typing').innerHTML = data.typing;
        if(!chatBox.classList.contains("active") && takeDown === true) {
          takeDown = false;
          $('html,body').animate({scrollTop: document.body.scrollHeight}, "fast");
        }
      }
    }
  }
  xhr.setRequestHeader("Content-Type", "application/json");
  xhr.responseType = "json";
  xhr.send(JSON.stringify(dataString));
}, 500);

Therefore, as an expected result what I need here is that I want the above first ajax request which is responsible for inserting the data to process in the background and should not hinder or slow down the second ajax requests which is responsible to fetch the inserted data. Users should not be made to wait until the mail is sent to be able to receive the sent data. The retrieval response should be instant after the data is inserted. In short, the ajax should be sending mail in the background without having to make the user wait for the response.

Relaxing Music
  • 452
  • 4
  • 13
  • Does this answer your question? [How to send emails using PHPMailer in the background?](https://stackoverflow.com/questions/23191522/how-to-send-emails-using-phpmailer-in-the-background) – nice_dev Oct 04 '21 at 04:38
  • You can also create cron job to send emails in an async manner. – nice_dev Oct 04 '21 at 04:38
  • Are you using sessions? It may block your concurent requests by long running scripts, if it is not closed before this long task. – Robert Oct 04 '21 at 05:10
  • @Robert you mean `session_start()` ? Yes. Of course I am. But I cannot close the session before attempting this task as the data is retrieved based on the session only. You can see than in the PHP part above. – Relaxing Music Oct 04 '21 at 06:49
  • @nice_dev just want to stay away from cron job unless there isn't a way with JS. – Relaxing Music Oct 04 '21 at 06:50
  • @nice_dev for that link you suggested, having a look. – Relaxing Music Oct 04 '21 at 06:51
  • 1
    _"But I cannot close the session before attempting this task as the data is retrieved based on the session only."_ - but you _can_ probably close the session, before you trigger the part of the script that is taking so long, the actual sending of the mail ... – CBroe Oct 04 '21 at 07:00
  • @CBroe hmm... let me try that! – Relaxing Music Oct 04 '21 at 07:05
  • @RelaxingMusic Since sending email is a backend job, JS can't interfere with the process. However, you can try a hack: Send request to the server, let server send the response. Now, send another AJAX request for sending email. Since AJAX is async, other operations can be carried on smoothly. Now, you don't have to bother about time taken to send the email at all. – nice_dev Oct 04 '21 at 07:06
  • 1
    @nice_dev that seems like a nice hack out there.. Let me try all these :) – Relaxing Music Oct 04 '21 at 07:07
  • @RelaxingMusic Sounds great. Note that for my suggestion, AJAX has to be nested or tied with `.done()` or `success` callback of the previous one – nice_dev Oct 04 '21 at 07:12
  • @nice_dev Yes, of course. That's exactly what I was about to do as the corresponding AJAX call depends directly upon the the previous one. However, what you mentioned `.done()` and `success`, they are for jQuery and not for vanilla JS, right? Vanilla has `.then()` I guess. – Relaxing Music Oct 04 '21 at 08:11
  • @RelaxingMusic Yes I meant via Jquery way. Never tried with vanilla javascript since there are ready made wrappers like Jquery AJAX available. With vanilla JS, it should be under `if(xhr.readyState === XMLHttpRequest.DONE) {` I presume. – nice_dev Oct 04 '21 at 08:35
  • @nice_dev Or, I can simply convert my Vanilla JS to jQuery for a much efficient use case. But jquery being a library can slow down a bit as compared to core JS. – Relaxing Music Oct 04 '21 at 08:46
  • @RelaxingMusic If you load it via CDN(as in CDN URL), it will be fast. There will barely be 10-15 ms difference which is quite negligible. I have never seen sites slow down because of inclusion of jQuery. – nice_dev Oct 04 '21 at 08:51
  • Aren't CDN's risky? What if their servers are down? That would break my site. Do they run backup servers? – Relaxing Music Oct 04 '21 at 09:24
  • it's more likely for your site to be down, than for a CDN to be down. – Kevin B Oct 04 '21 at 18:25
  • @KevinB I will make sure it doesn't :) – Relaxing Music Oct 05 '21 at 01:53

0 Answers0