jquery $.ajax request remains pending - php

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

Related

Create a waiting page with PHP and twig

I post data to a page and make some checks that take 5-6 seconds. I would like to insert a waiting page to improve the user experience.
My code is like this:
....functions that take time
echo $twig->render('template.html.twig',[ variables ....]);
Because PHP calls the twig template at the end after processing the data I cannot use a javascript solution.
I tried rendering a waiting template first, then process the data and store the output in a session variable then after that send a location header to the results page but I found PHP does not echo the waiting template untill it finishes the whole script even if i call it in the beginning.
echo $twig->render('waiting.html.twig',[ variables ....]);
....functions that take time
store output as session variable.
send location header to another page that renders the template from the session variable
How can I achieve a waiting page?
You could always store the data temporarily and load a dummy "loading page" for the user. And right when the dummy page loads you send an ajax request that recovers your data and processes it. When the ajax call returns you could do your redirection or whatever it is you want to do when the process is done.
When I say "store the data temporarily" I mean in a database or a file, etc.
The solution I ended up doing was the following:
Call the page by Ajax and display a waiting page.
function submit_form(file_method) {
var spinner = $('#loader');
spinner.show(); //show waiting div
var request = $.ajax({
url: "upload.php",
cache: false,
contentType: false,
processData: false,
async: true,
data: form_data,
type: 'POST',
success: function (res, status) {
if (status == 'success') {
window.location.href = 'results.php';
} },
error: function (jqXHR, textStatus,res) {
spinner.hide();
alert('Error encountered: '+textStatus+'-'+jqXHR.responseText);
} })
};
In the php page, store the output as an array in a session variable.
....functions that take time
$_SESSION['result'] = [RESULTS .......]
After the ajax call is completed successfully the user is redirected to a new page. The new page uses the session variable to call the template.
echo $twig->render('waiting.html.twig',$_SESSION['result'] );
unset($_SESSION['result']);
Simplest solution is to add 'waiting page' inside first page but hide it. When user presses button browser will send request, but will still wait for response showing old page. Here you can show it using JS.
In short - user presses button, you show template (which was already there but hidden) and then browser just waits for response with your template in front.
But best way would be to use AJAX like Patriot suggested.

Calling PHP on another server from Javascript, and waiting for it to complete

I have a PHP script on my server that needs to be run from my clients websites using Javascript in a plain HTML page. After the script is run the HTML page will redirect. The problem is that sometimes the script doesn't run before the redirect happens.
This is the code I am using...
$.ajax({
async: false,
type: 'GET',
url: 'the_URL_of_the_PHP_on_my_server.php',
success: function(data) {
}
});
window.location="the_URL_for_the_redirect";
The PHP script on my server is to track hits/sales etc. Is there are way I can force the page to wait for the script to complete before the page redirect.
The HTML page and the PHP page are on different servers. Also, the HTML page is being used on lots of different websites, so I can't give them all permission to access my server. I'm not sure if that's causing a problem or not.
I don't need any information back from the PHP script I just need it to run.
Thank you.
The success function runs when you get a response (unless it was an error, in which case the error function you haven't defined would run).
If you want some code to run after you get a response, put it inside those functions instead immediately after the code which sends the request.
That said: The point of Ajax is to talk to the server without leaving the page. If you are going to go to a different page as soon as you have a response, then don't use Ajax. Use a regular link or form submission and then having an HTTP redirect as the response.
This is normal, that this situation happens.
because $.ajax is async and won't wait till success method
change your code to
$.ajax({
async: false,
type: 'GET',
url: 'the_URL_of_the_PHP_on_my_server.php',
complete: function(data) {
window.location="the_URL_for_the_redirect";
}
});
UPDATED
changed function success to complete
difference is =>
complete will be called not matters what happened with request
UPDATE 2
think about #Quentin variant by html redirects.

Why my AJAX function blocks the header of PHP that I have on my page?

I am doing a program in PHP (MVC) in which I need to delete a row from the database when I click on a link on the View side. So, when I click on the link, the following ajax function it is called.
var deleteCar = function(id)
{
$.ajax({
type: "POST",
url: "http://localhost/project/car/deleteCar/" + id,
success: function(response){
}
});
}
but I do not want to send any data so it is the reason why I put it as above.
Then, in the Controller side I have the following method:
public function deleteCar($id)
{
//Here I call the function to delete the Car that I send by id. It works fine.
header('Location: http://localhost/project/car');
}
If I call directly the method deleteCar on the link without Ajax the header works properly but in the same moment I use Ajax to call it, I have to refresh the page to see the content that I have modified, I mean, that the Car have been deleted.
The code works fine, just I do not want to refresh the page after AJAX function had finished.
Thanks in advance!
I am guessing the use case is to allow the app to work when the user does not have JS enabled - so they just click the links and get a non-AJAX experience. In this case you probably want to redirect ONLY if the page was requested via GET, not POST. something like
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
header('Location: http://localhost/project/car');
}
is likely what you are looking for.
You will then have to actually remove the element representing the car from the DOM in your success handler, with something like:
var deleteCar = function(id)
{
$.ajax({
type: "POST",
url: "http://localhost/project/car/deleteCar/" + id,
success: function(response){
$('#car-row-' + id).remove();
}
});
}
(that won't be it exactly, it depends how the HTML of your page is setup how exactly you will do this).
I believe the key thing to understand here is - when your PHP function has completed it has removed the car from the database, but the browser still has the same HTML it got from the page originally. Just sending an AJAX request won't change that. If you want the HTML in the browser to change to reflect the new state of the database, you will NEED to do one of two things:
Refresh the page, so the entire thing is rebuilt by PHP based on the current database state
Use javascript to change the HTML in the browser, to reflect the changes you have made to the database state.
It is wrong on so many levels but it's difficult to put in words. It's subtle.
Long story short - think about jquery.ajax as of another virtual tab of you browser.
When you make ajax-request to the server - you create new virtual tab.
You php header could affect this virtual tab and redirect it where that header defined.
But it will redirect that virtual tab, not your current tab - if that makes sense.
What are your options? On success - make redirect with pure javascript.
success: function(response){
location.href = "http://localhost/project/car";
}
This would be the basic way to solve your problem.

Is it possible to 'echo' a sequence of responses from an ajax call

I'm learning and experimenting with jquery/ajax as I develop a website. I have a page that updates a database. I would like a 'sequence' of responses to display on the screen when the user submits their data (I've seen this done on many other sites).
For instance... user submits form and the page displays:
Received Input
Checking Database - recond number xy
Updating Database
Retrieving Information
etc etc
This is just an example but you get the idea.
I have an ajax call that is initiated on 'click' of the submit button (getFormData just serialises all the form data for me and works fine):
var toSend = getFormData($upgrade_db_form);
var formMessageBox = $("#displayResults");
$.ajax({
url: ajaxurl,
data: {
action: "database_action",
formData : toSend
},
type: 'POST',
dataType: 'TEXT',
beforeSend: function() {
//$form.fadeOut('slow');
formMessageBox.html("starting it up");
},
success: function (data) {
formMessageBox.empty();
formMessageBox.html(data);
error: function (xhr) {
// formMessageBox.html("Oops error!");
}
});
I have a function which gets called by ajax:
function upgrade_database_function() {
echo "testing ";
for($i = 0; $i < 99; $i++) {
echo "percent complete ".$i."%";
}
echo "done ";
die(); // this is required to return a proper result
}
I'm using Wordpress and all the ajax side of things works fine, it passes the form data correctly etc, it's just that I get one long output as though it's cache'ing all the echo's up instead of outputting them in sequence.
I've gone through the jquery ajax documentation and couldn't find how to make it behave the way I want it to. I can live with it the way it is but I think it would look a lot better if I could get it working the way I would like.
Can this be done this way or do I need lots of sequential ajax calls to make it work?
I don't know PHP, but i'm guessing that the echo is just writing to the response buffer... so when all the echos are done the whole response will be returned and you would get the effect that you are seeing... You would need to go with a polling system or something along those lines to get the latest status' from the server and display them I would think... Maybe there is some system in PHP that allows this, but as I said, I don't know PHP.
An Example of Long Polling can be found in this article.
http://www.abrandao.com/2013/05/11/php-http-long-poll-server-push/
WARNING: You may have to do some manual managing of locking of the session in PHP so that your long running call doesn't lock your polling ajax calls: See here:
http://konrness.com/php5/how-to-prevent-blocking-php-requests/
Note that you would likely be wanting to:
create one ajax call that starts the execution of some coded that will take a while... you could put messages that have been generated into a session variable for example in a list of some sort. You would need to lock/unlock the session as mentioned to prevent suspension of AJAX polling calls.
you would create a polling method like in the article that might check the session every 500ms or something to see whether there are any more messages, lock the session, remove those messages and return those messages to the client side and display them.
WARNING: Again, I'm not a PHP person, I may have done this once in my life in PHP (can't remember exactly) but I may be wrong and this may not work, from what I've seen though it looks like it is achievable. Hope this gets you on your way!

AJAX Post Not Sending Data?

I can't for the life of me figure out why this is happening.
This is kind of a repost, so forgive me, but I have new data.
I am running a javascript log out function called logOut() that has make a jQuery ajax call to a php script...
function logOut(){
var data = new Object;
data.log_out = true;
$.ajax({
type: 'POST',
url: 'http://www.mydomain.com/functions.php',
data: data,
success: function() {
alert('done');
}
});
}
the php function it calls is here:
if(isset($_POST['log_out'])){
$query = "INSERT INTO `token_manager` (`ip_address`) VALUES('logOutSuccess')";
$connection->runQuery($query); // <-- my own database class...
// omitted code that clears session etc...
die();
}
Now, 18 hours out of the day this works, but for some reason, every once in a while, the POST data will not trigger my query. (this will last about an hour or so).
I figured out the post data is not being set by adding this at the end of my script...
$query = "INSERT INTO `token_manager` (`ip_address`) VALUES('POST FAIL')";
$connection->runQuery($query);
So, now I know for certain my log out function is being skipped because in my database is the following data:
alt text http://img535.imageshack.us/img535/2025/screenshot20100519at125h.png
if it were NOT being skipped, my data would show up like this:
alt text http://img25.imageshack.us/img25/8104/screenshot20100519at125.png
I know it is being skipped for two reasons, one the die() at the end of my first function, and two, if it were a success a "logOutSuccess" would be registered in the table.
Any thoughts? One friend says it's a janky hosting company (hostgator.com). I personally like them because they are cheap and I'm a fan of cpanel. But, if that's the case???
Thanks in advance.
-J
Ok, for those interested.
I removed the full URL http://www.mydomain.com/functions.php
and replaced it with the local path functions.php and that did the trick.
Apparently AJAX has issues with cross domain ajax calls and I'm not on a dedicated server, so I imagine what's happening is every couple hours (or minutes) I am somehow hitting my script from a different location causing AJAX to dismiss the POST data.
-J
Try enabling error reporting on the jquery $.ajax function, your code would look something like
function logOut(){
var data = new Object;
data.log_out = true;
$.ajax({
type: 'POST',
url: 'http://www.mydomain.com/functions.php',
data: data,
success: function() {
alert('done');
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus+" - "+errorThrown);
}
});
}
See if that sheds light on your situation.
I have a strong feeling that it's more of a server side issue rather than the client's.
The odd thing is that you see the problem for a period of time. If the client works at all, then at the minimum refreshing the page or restarting the browser should fix it.
The die() at the end of the function is suspicious, but I am not quite sure how it will affect it.
Btw you can see http headers in FireBug's Net tab, to know whether those parameters has been sent properly.

Categories