Ajax Call Hangs Browser - I don't care about the response - php

How do I abort an Ajax call if I don't really care for the response as I don't want to hang the browser?
The situation is I have an ajax call that could trigger the server sending over a 1000 emails in some cases. 99% of the time it is only a few or tens of emails.
So with the 1000 email ajax call, the browser waits sometimes 5 minutes before it gets the success message, thus the user has to wait.
I have tried setting a timeout, but this still hangs. I'd like to wait about 20 seconds and then abort waiting for the response.
var request = jQuery.ajax({
type: "post",url: "admin-ajax.php",
data: {
action: 'send_email',
emailHTMLMessage: tinyMCE.activeEditor.getContent(),
_ajax_nonce: '<?php echo $nonce; ?>'
},
timeout: 20000, //Set your timeout value
success: function(html){ //so, if data is retrieved, store it in html
window.scrollTo(0,0);
sendResults(html);
},
error: function(jqXHR, textStatus, errorThrown) {
if(textStatus==="timeout") {
<... I'd redirect to another html page here....>
} else {
alert("Another error was returned"); //Handle other error type
}
}
}); //close jQuery.ajax
I have tried request.abort() but this kills it immediately and the server never gets the send_email message.
How can I quietly ignore the response after 20secs while the server carries on doing it's thing?

In this post there are afew ways to keet the script running after the http request ends:
Can a PHP script start another PHP script and exit?
So you can leave your email script running on the server.
If you want to know the status you could make your email script update to a mysql table how many emails are sent and check with an ajax request the count from the mysql table.

If you're sending 1000 emails, that call is going to contain some overhead no matter what you do. You are also going to have to wait until all the information is sent to the server before you want to allow the user to leave the page as well.
My suggestion would be to change the server code to respond as soon as the server gets their request. That way the client isn't waiting on the server to finish sending the entire batch, rather just waiting for their request to be received by the server.

Just post without using the success, timeout or error callbacks.
You might want to try creating a new get request for each email:
for(i = 0; i<1000; i++){
var request = $.ajax({
type: "post",
url: "admin-ajax.php",
data: {'i':'nada'}
});
};
In this case, I used a for loop, but you could also use an array of emails:
var emails = new Array(1000);
$.each(emails, function(){
var request = $.ajax({
type: "post",
url : "admin-ajax.php",
data: {'i':'nada'}
});
});

Related

AJAX request body randomly empty on server side

I have a browser-based client that makes AJAX calls to a PHP/Apache back-end. When a button is clicked, the client loops through a list of "providers" and sends an Ajax request to each of them with exactly the same payload.
Randomly some of the requests in the loop are arriving at the server side with a blank POST body. What is really strange about this is the fact that other requests in the same loop are arriving properly populated. Sometimes we are seeing all of the items in the loop arriving with a blank body, sometimes some in the loop. It is really strange!
Environment details:
Client = JQuery 3.3.1, JQueryUI 1.12.1, Bootstrap 3.3.7, JQuery validate 1.19.0
Server = Apache 2.4, PHP 7.1
We cannot actually reproduce the problem in a development environment, but logging in production is clearly showing that this is happening regularly on a daily basis (maybe 5% of requests). We have deployed monitoring on the client browsers to trap any errors and there is nothing in terms of exceptions or anything that looks like it could be related.
The sample below shows what we are doing on the client side.
1) bind a click event to
2) when clicked, populate a request object
3) loop through the list of "providers", posting request from 2 to PHP server
$(document).ready(function() {
bindEvents();
}
function bindEvents() {
$("#myButton").click(function(event) {
event.preventDefault();
handleClick();
});
}
function handleClick() {
var request = ...;
...
var save=false;
if (....) {
save=true;
}
var providers = ["provider1", "provider2", "provider3", "provider4", "provider5", "provider6"];
var ndx;
for (ndx=0; ndx<providers.length; ++ndx) {
doRequestSend("action/"+(save?"save":"verify"), request, providers[ndx]);
}
}
function doRequestSend(action, request, provider) {
request['apiKey']=getAPIKey();
var url=baseURL+"/api/"+provider+"/"+action;
$.ajax({
type: "POST",
url: url,
data: JSON.stringify(request),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data){
...
},
failure: function(errMsg) {
...
},
error : function(jqXHR, textStatus, errorThrown) {
...
}
});
}
Obviously, it is difficult to figure out the issue when I cannot reproduce. However, am hoping the someone might spot a problem with the approach that could be resulting in the issue.
Alternatively, open to any random/crazy ideas that could explain HOW this could possibly be happening! Some requests in the loop arrive fine, others arrive blank!
Notes:
- Although the loop POST to a slightly different url with each iteration, on the server side, they all end up at the same entry point and the first thing that is done is a log of the body (this is how we know it is blank!)
- The only browsers that (to date) seem to have experienced the issue are Chrome 73 & 74 on Windows. This might not be relevant!
Anyone got any ideas or things to try that might track down the source?
Cheers!

How to execute multiple HTTP Request to the same page from the same client

I want to run some AJAX calls at the same page from the same client.
Ajax calls start correctly but the server queued the requests and execute jsut one per time.
I've also check the start request time and the returned message time.
Studying the second one there's a difference between the requests which is multiple than the before request.
Help me please!
$("document").ready(function() {
$(".user-id").each(function() {
var id = $(this).html();
getData(id);
});
});
function getData(id) {
$.ajax({
url: 'loadOperatorDiagram.php',
type: 'GET',
data: {id: id},
async: true,
cache: false,
success: function(resp) {
$("#boxes").append(resp);
draw(id); // A javascript function which draw into a canvas
}
});
}
loadOperatorDiagram.php get some queries and its execution time is about 5 seconds. The first one ajax request response after 5 seconds, the second one after 10 and so on. But everyone starts asyncronusly and correctly with a difference of few milliseconds
If you are using sessions in php (sounds like it, otherwise you could do at least 2 simultaneous requests...), you should close it as soon as possible in your php script as php will block the session.
Just use session_write_close(); as soon as you have what you need from the session.

JQuery Ajax using post - is it blocking?

Is there a way to make jQuery's post method wait for server side code to complete?
In my example below, post is not waiting for my php script to finish. Though php is calling sleep(10), post returns right away, resulting in javascript clearing out the value in #temsg and changing the text of $sendmsg too early.
$('#sendmsg').click(function() {
$("#sendmsg").html("sending....");
var msg = $("#temsg").val();
var to_id = 123;
$.post("http://localhost:8888/ci/index.php/members/addMessage",
{message: msg, tomember: to_id},
function(data){
$("#temsg").val('');
$("#sendmsg").html("Leave Message");
},'json');
$("#infomsg").show();
$("#infomsg").html("Message Sent!");
setTimeout(function() { $("#infomsg").hide('slow'); }, 3000);
});
Ajax is (supposed to be) asynchronous - that means that the $.post() method is non-blocking and returns immediately and the rest of your function continues executing, and then eventually when a response comes back the success handler is called.
You can make the JS code pause until the Ajax request returns by doing a synchronous (blocking) request, but given that (most) browsers run JavaScript on the same thread as the UI that means the browser will not respond to anything until the response comes back which is horrible for the user - essentially the browser would be locked up for the ten seconds that your server-side code is sleeping.
The solution is to stick with the default asynchronous request but move the code from after your $.post() call into the success handler:
$('#sendmsg').click(function() {
$("#sendmsg").html("sending....");
var msg = $("#temsg").val();
var to_id = 123;
$.post("http://localhost:8888/ci/index.php/members/addMessage",
{message: msg, tomember: to_id},
function(data){
$("#temsg").val('');
$("#sendmsg").html("Leave Message");
$("#infomsg").show();
$("#infomsg").html("Message Sent!");
setTimeout(function() { $("#infomsg").hide('slow'); }, 3000);
},'json');
});
Ajax is asynchronous. The fact the code keeps running doesn't mean the sleep didn't occur.
That thread on the server "sleeps" , while javascript continue executing the next lines.
Example how to use async:false:
$.ajax({
url: "http://localhost:8888/ci/index.php/members/addMessage",
async: false,
data: {message: msg, tomember: to_id},
dataType: 'json',
success: function(data){
$("#temsg").val('');
$("#sendmsg").html("Leave Message");
}
});
ajax docs

jquery $.ajax request remains pending

I have made a simple chat application which uses long-polling approach using jquery,
function sendchat(){
// this code sends the message
$.ajax({
url: "send.php",
async: true,
data: { /* send inputbox1.value */ },
success: function(data) { }
});
}
function listen_for_message(){
// this code listens for message
$.ajax({
url: "listen.php",
async: true,
timeout:5000,
success: function(data) { // the message recievend so display that message and make new request for listening new messages
$('#display').html(data);
listen_for_message();
}
});
}
THIS SHOULD HAPPEN : after page loaded the infinite request for listen.php occurs and when user sends message, the code sends message to database via send.php.
PROBLEM is, using firebug i've found that send.php request which is performed after listen.php request, is remains pending. means the request for send message is remains pending.
The issue was because of session locking;
both send.php and listen.php files use session variables,
so session is locked in listen.php file and the other file (here send.php file) can't be served after the session frees from serving another file ( here listen.php).
How do I implement basic "Long Polling"?
the link above is a similar question that may help you.
it does not have to be on a database, it can be saved on a tmp file, but your problem is that you are choking the browser by performing too many requests, any one browser handles two requests at a time, which means you should really allow the browser to finish the first requests first then do the second one... and so on...
you do not need to do send.php and listen.php, because you can do it simply on one page both of them.
function check(){
$.ajax({
url : 'process.php',
data : {msg:'blabla'/* add data here to post e.g inputbox1.value or serialised data */}
type : 'post',
success: function (r){
if(r.message){
$('#result').append(r.message);
check();//can use a setTimeout here if you wish
}
}
});
}
process.php
<?php
$msg = $_POST['msg'];//is blabla in this case.
$arg['message'] = $msg;//or grab from db or file
//obviously you will have to put it on a database or on a file ... your choice
//so you can differentiate who sent what to whom.
echo json_encode($arg);
?>
obviously this are only guide lines, but you will exhaust your bandwidth with this method, however it will be alot better because you have only one small file that returns either 0 to 1 byte of information, or more if there is a message posted.
I have not tested this so don't rely on it to work straight away you need a bit of changes to make it work but just helps you understand how you should do it.
however if you are looking for long pulling ajax there are loads of scripts out there already made and fine tuned and have been test, bug fixed and many minds help built it, my advice is don't re-invent the wheel

inform user during php calculation w/jquery

I'm writing code in PHP that analyzes user input.
I'm hoping to analyze it through a AJAX request using jquery.
I'd like to provide real-time feedback to the user while I'm preforming the calculations.
For example:
"Uploading your input", "Analyzing", "Preparing final result" and so forth.
How can I go abut doing this?
You will have to have a different back-end script do the processing than the one you are sending your request to. Your original ajax request can store the user input to be analyzed, and another process check for new data to work on regularly and start working when it finds some. That background process can then record its progress, e.g. using a file or a database.
The subsequent ajax requests will check that progress file or database entry and display the progress to the user.
Another (more complicated) solution would be to use Comet to push information on the status from the server to the browser. There is a comet plugin for JQuery in the works, as described in StackOverflow question 136012.
Assuming you have a service located at /service-status.php that checked the status of the job and returned a string you could do something like this in a interval.
var intervalId;
intervalId = setInterval( function() {
$.ajax({
type: "POST",
url: "/service-status.php",
data: "jobid=" + id,
success: function(msg){
if (msg === 'Finished') {
clearInterval( intervalId );
}
alert( "Status: " + msg );
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("He's dead Jim"):
clearInterval( intervalId );
}
})
}, 500);
This would poll your service every 500ms. It also assumes that you return 'Finished' when done. Adjust accordingly. I might put a counter in there too to clear the interval just in case so you don't DDOS your own server.

Categories