How can I interrup slow ajax request, running in background - javascript

The situation:
User visit some fast loading page, that makes an AJAX async request to some slow PHP script, that loads, for example, for 30 seconds
After 3 seconds user clicks some link to go to another fast loading page, but browser waits 27 seconds to finish AJAX request to slow script, and only after that starts to load next page
How can you solve this problem? How to tell web server to interrupt processing the request, started with defined AJAX call?
PS. abort() is not the solution
PPS. The code example: my page includes filter of shop products, that loads longer that other page components. After first load filter is cached - next times it loads fast. So when page loads, I don't show filter, but add a JS, that calls current page again using AJAX, adding some parameter (SHOW_FILTER). If page receive this parameter - it shows filter...
<div id="catalog_filter_container">
<?if($_REQUEST['SHOW_FILTER'] == "Y"):?>
... filter code here ...
<?endif;?>
</div>
<?if($_REQUEST['SHOW_FILTER'] != "Y"):?>
<script type="text/javascript">
$(document).ready(function(){
$.ajax({
url: "<?=$APPLICATION->GetCurPageParam("SHOW_FILTER=Y", array("SHOW_FILTER")); // get cur URL with adding param SHOW_FILTER=Y ?>"
})
.done(function(html) {
$("#catalog_filter_container").append($(html).find('#catalog_filter_container'));
});
});
</script>
<?endif;?>

If I understand you correctly it is not neccessary to have an ajax-call because the page is reloaded anyway. This seems like something you can do server-side only (with sessions).
Something like this: (If the thing you want to achieve is store a value to filter when filter not set and display the value from filter when it is set)
<?php
session_start();
?>
<div id="catalog_filter_container">
<?if($_REQUEST['SHOW_FILTER'] == "Y") {
$_SESSION['filter_content'] = 'bla bla bla';
}
else {
echo $_SESSION['filter_content'];
}
?>
</div>

Try using a cron job to run the queries separate from page loads and cache the results on the server. Then have your AJAX request return the cached content.

Related

Loading screen while Servlet loads

I have this JSP where I select certain parameters and hit "submit" button, after clicking "submit" I am calling a JavaScript function as below
<body>
<input type=button class="button" id = "submit" value="Evaluate"
onclick="JavaScript:return evaluateFunction()">
</body>
and in the evaluateFunction() I am collecting all the parameters and call a new Servlet in new popup window as below:
<script>
function evaluateFunction(){
var win = window.open('ConfirmEvaluate?parameters,'mywindow','width=600,height=500,titlebar=no')
}
</script>
Now the issue is ConfirmEvaluate servlet takes some time to get the data from database(around 15-20 secs based on size of input) and displays the data in the forwarded JSP(say userdata.jsp)
Now I want to display a loading gif or screen in that 15-20 seconds while the Servlet loads the data from database.
How can I proceed, any help would be appreciated.
I have already gone through some similar questions in SO but none of them is having a specific answer.
You have to use AJAX. Servlet requests like the one in your example are synchronous. Which means it will wait until the processing finishes then do the next activity.
With an AJAX request you can send the request and then do something else without having to wait for it to finish processing, because it is asynchronous.
The way i would approach this is in the following way:
You get the user details in ConfirmEvaluate, and redirect the user to userdata, then once the user is on the page do the AJAX request to fetch the information that takes a long time to process. When the request is made you can show a loading icon but when you get a response from the AJAX request, you can hide this loading icon. Check out this brilliant post on how to make AJAX requests with servlets
I had to implement something like this recently, here is some example code:
<script>
//when page loads, the ajax request starts
$(document).ready(function() {
$(this).scrollTop(0);
getposts(username);
});
//ajax request that will show and hide the loader depending on response
var getposts = function (username) {
var params = {
user: username
};
$.get("../GetUserFeed",$.param(params),function(responseXml) {
$("#user-feed").append($(responseXml).find("feed").html()); // Parse XML, find <data> element and append its HTML to HTML DOM element with ID "somediv".
$('#logo-loader').hide();
if(isBlank(responseXml)){
$('#logo-loader-completed').show();
$('#logo-loader-image').hide();
}
});
};
</script>

Calling multiple html page from php consecutively

I am not well versed in php. I tried different answer from stackoverflow but was not successful in solving the problem.
I got a HTML form with a submit button. After submitting I call a php script and which in turn calls an executable file which runs some algorithms on the submitted data from the html. At the end I echo the result of the analysis through the php.
<?php
$ex=shell_exec("...");
if($ex == "Run Successfully\n"){
echo"<html>
<meta http-equiv= refresh content='0.1;URL=--.txt'>
</html>";
}
?>
Till this works fine but my algorithm takes 30-40 sec to run and all that time my original html page remains in screen which looks like nothing is happening there. So I created a new html page with a progress bar animation. Now I want to show the progress bar while the executable is running and when the result is available I want to replace the progress bar page with the result page as before.
I tried echo file_get_contents("waiting.html");
header ("location: waiting.html");
But none of them works as I planned. All the time they are coming up only after the executable finish working and not before that.
If someone can help me with some suggestion I shall be grateful.
Thanks in advance.
This is where jQuery and AJAX would work very nicely. What you could do is start with the loading animation, and use jQuery to call the php file with the shell_exec with ajax. Once the ajax is .done(), then you can replace the text with the results. If you need me to clarify, just let me know.
However, if you don't want to use AJAX, PHP is run line by line. Therefore, you would want to put your progress bar before the shell_exec. This would mean that you would not be able to use header location since headers have already been sent.
Edit (AJAX Example):
This would be a quick example of how to make this happen.
Create two php files:
progress.php
Load jQuery
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
url:'algorithm.php',
type: 'post',
cache: false,
success: function(data) {
//Replace with how you want to format the page
}
});
});
</script>
Loading Bar
algorithm.php
<?php
$ex=shell_exec("...");
if($ex == "Run Successfully\n"){
die('{"status":"success"}');
}
?>
Now you don't have to use json as an output. You can also have html output. Let me know if I should clarify anything.

jQuery Auto refresh div messing up

I have a script that auto-refreshes a certain div on the page (That I got from another post on here)
<script type="text/javascript">
var auto_refresh = setInterval(
function(){
$('#refresh').load('index.php?_=' +Math.random()).fadeIn("slow");
}, 10000); // refresh every 10000 milliseconds
</script>
...............
<div id="refresh">
<!-- Some PHP Code -->
</div>
This refreshes, however when it does, I takes the entire html document and puts it into the div. Like this:
As you can see, the refreshed div (the one marked in red) is getting the body shouved into it. Any ideas???
You are loading entire page to the div.
Modify the code to use only part of the document that is fetched:
<script type="text/javascript">
var auto_refresh = setInterval(
function(){
$('#refresh').empty();
$('#refresh').load('index.php?_=' +Math.random()+' #refresh').fadeIn("slow");
}, 10000); // refresh every 10000 milliseconds
</script>
First off, you are loading the entire page into the divider, thus causing the file to reload entirely. Instead, you should be having the Recent Posts divider load from a single file, even on the first page load. Then have that consistently refresh over time.
Secondly, you should be transferring as little data as possible from your server to your clients. At most, you should use a minimalistic checksum of sorts (number of messages, for instance) to confirm that the client and server are synced up.
Lastly, if you choose to use this format, aim to transfer your data in something such as JSON or XML and have the client display it on the page. Transferring the styled HTML increases network overhead and is not the best practice.

ajax div reloads with correct data, but with entire webpage within div

I have a div that contains a student's schedule, and there is a drop-down box for selecting by semester.
Once they select the semester, there is an ajax post, but when it refreshes, it displays the entire website within that div (with the appropriate schedule for that semester).
It looks like an iframe within a webpage, as seen here: http://cl.ly/Dy3b
Here is the ajax post script
<script type="text/javascript">
$(document).ready(function() {
$('#term').change(function() {
var form_data = {
term : $('#term').val(),
ajax : '1'
};
var u = $("#schedulePortletURL").attr("href");
$.ajax({
url: u,
type: 'POST',
data: form_data,
success: function(msg) {
//alert(u);
$('#view-schedule').html(msg);
}
});
return false;
});
});
</script>
If possible, could you give me some suggestions of what to investigate to correct this? Thank you
My guess is that the call to the server is returning a full HTML page, and your code then puts the full HTML page into the view-schedule div.
To resolve this, create a new HTML page that you can call that contains a html fragment - the chunk that you want to live in the view-schedule div. Then change schedulePortletURL to point to the new HTML page.
Alternately, you could get the html back (the msg) and parse it to pull out the data you are interested in, then insert the filtered data into the view-schedule div.
Does the existing website have a API at all that you can call?
Another possibility is that some kind of error checker in your server-side script is mistakenly firing and causing a redirect to some web page. That web page is then retrieved by the AJAX, then displayed in the DIV. I have had this happen before. You should check your server side script.
If you do not have full control over the webpage you are fetching the fetched page should be considered unpure and you should use iframe. Remember that with .html(blob) you will also get javascript code, flash objects etc. which can be used to compromize your users.
If you on the other hand have full control over the fetched webpage (which I assume) you should make a if-statement in your template that checks if the request is ajax-based.:
Pseudo serverside template code:
if not request.is_ajax():
import header.html
import body.html
if not request.is_ajax():
import footer.html

Preloader for dynamic content

I have dynamic page which takes about 8 seconds to load searched data.
Problem is, all browsers remain on old page for those 8 secs & show dynamic page only after it
loads completely.
What I want is preloder image to be shown to the customers until second page gets load.
How can I achieve this?
Thanks
I assume you are loading the second page through AJAX. If so, you'll only be able to display the results after the asynchronous call returns.
However, nothing prevents you from making changes to the page before sending off the AJAX request. The basic structure will be:
var preload = $('<div></div>').text('I am preloading!').insertAfter('somewhere');
$.get(..., function() {
preload.remove();
// insert your real content, received from this AJAX request
});
$('<div id="busy">Loading...</div>')
.ajaxStart(function() {$(this).show();})
.ajaxStop(function() {$(this).hide();})
.appendTo('body');
That's all!
You may want to add some style to #busy tag, but this you can do with CSS.

Categories