overcome ajax page refresh - javascript

I am building a application with many form submissions and using ajax to send data to server (node js). I have a table to be updated on a button click , and on click I need to load a spinner and call the ajax post request to server. On server it takes some time to update and send back result to ajax success. So on ajax success I hide the load spinner and update the data to table. Everything works fine problem is meanwhile when ajax req is called and server side is executing query the user may reloads the page, when page reloads ajax call is cleared so i cannot hide the load spin and update success data to html. What is the possible solution to avoid this
$.ajax({
url: url,
type: 'POST',
processData: false,
contentType: false,
data: formdata,
success: function (data) {
if (data.status == 'Success') {
toastr.success(data.msg);
// code to hide load spin
// update result data to html
}
})

You can do three things listed below in the order of complexity:
1. Put warnings on the page for users not to press reload or back buttons. This approach is often adopted on payment gateways when credit card details are verified server side. You can show a modal dialog box with the warning and spinner graphic.
2. Use session variables on server side to detect interruptions to ajax calls. For example you can have a variable called ajax_status (values none, incomplete and complete). You can set this variable at the start and successful completion of an ajax call. On page load, if you find the variable set to incomplete, show an error message, saying ‘something went wrong, have you pressed the reload button?’
3. Extend the 2nd approach to save ajax call parameters and reinitiate the request on page reload (show a warning saying data refresh was interrupted and reinforce message re not reloading).

You can avoid a page refresh(re-load) while all of your code is being executed by changing your html form action -
<form id="myForm" action="javascript:void(0)"></form>
This will also maintain HTML standards without fancy code to manipulate element functions.

Related

Ajax and page refresh

I am building a web app and one of the functionalities is to trigger an action in the backend which can take up to 5 minutes. This 'action' is a process which will run totally on its own (regardless of the front-end/back-end of my web app).
There is a form on the client-side which I use JavaScript to grab the data, clean it up/validate and send an Ajax call to my backend to start the process (which can take up to 5 minutes).
My question is, what if the user refreshes the page? The backend will still be triggered and run on its on, but I wanted to be able to capture the response back to the browser once the process is done in the back end. Is that viable/possible?
My Ajax is a pretty simple POST request to my backend:
$.ajax({
type: 'POST',
url: '/add-user',
data: {'data': JSON.stringify(data)},
//contentType: 'application/json;charset=UTF-8',
success: function(response){
console.log(response['message'])
}
//timeout: 3000 // sets timeout to 3 seconds
});
Please refer to this question prompt-user-before-browser-close
The only solution is to display a loading bar or spinner on the page while your page is waiting for the server task to finish.
If the user wants to navigate away you can use the confirm prompt.
I highly suggest using a websocket connection and if the user really closes, then inside window.onbeforeunload you should send a message and notify the backend to cancel the request context and stop the task from running. Running something like this without this protection can make your backend easy to get bombed.
PS. If it's a process independent of your backend then you should have scripts in place to kill it if the request context is canceled.

Problems using Ajax calls in reloaded page

I am a novice writing a website using jquery and jquery mobile. This loads a set of questions in the form of a JSON file, using jquery ajax, and then users work through questions. On first opening, the page successfully opens 2 JSON files using code that looks like this:
function loadJSON (keytoload) {
$.ajax({
url: keytoload,
dataType: "json",
async: false,
success: function (keyloaded) {
dataset=keyloaded;
},
error: function (request,error) {
alert('Error has occurred please try again!');
}
});
}
I find that async has to be set to false for this to work. If async is true, the page is displayed without the data from the JSON file.
After the user works through a series of steps, a new JSON file is loaded to replace the first and this usually works fine. However, reloading the page is erratic. It works fine in Firefox/Chrome on Windows, but throws an error if a page refresh is done when loading on Android Chrome. So I assume there is a problem in my code somewhere.
Is there a better way I could do this?
Your problem here is cause by the fact that you don't use ajax correctly. You don't know how long is going to take until the result comes back from the server.
A correct architecture here will be:
display an loading div before starting ajax.
On success add the questions in the page.
On next display the loading again.
On success render the new content.
Just setting an variable on success is wrong; on success you render the content based on the values from backend. Also using an ajax in a synchronous way is not recommended, since it can block the script.

Jquery - Clear or Remove the URL parameters

Regards, I'm doing a password recovery system in PHP, MySQL and AJAX, the system generates a link with an encrypted code and sends it to the user's mail.
Example of generated encrypted link:
$link = www.dominio.com/reset/?code=98rudrm2093xda
The user has to open the link from your email, to confirm the request, the site detects the code of the URL, using PHP and AJAX desencrita and compares it with the code for the database, if it exists then it creates a new password, this is all done in AJAX, but there is something, if the user returns to reload the web, you are receiving an alert that the code does not exist in the database.
Question:
As I can erase the code of the URL with jQuery, then reset the password, to prevent the alert window appears if I refresh the web page.
Is this possible?
I appreciate your help very much!
What I'm understanding from your question is that you want a method to set up the password reset and not allow re-resetting.
Send email with coded link
Have user click the link and visit the page
Page will get the code GET parameter (PHP or JS)
Do some magic to check if code exists in database (PHP)
If code exists, then allow password reset and delete code from database (PHP)
If not, show error message (PHP)
Redirect to index.html or index.php afterwards (JS)
The last step is to remove the URL variables. If the user checks that same URL again, it will go from step 3 on. Step 4 should stop a re-reset of the password.
You could use this which would technically refresh the page.
window.location.href = window.location.href.split('?')[0];
If you didn't want to refresh or redirect you could use this .pushState() which will update your browser history and change the URL on the page. This would prevent refresh, but hitting the back button on your browser would trigger the refresh again.
EXAMPLE: history.pushState('/some-url');
You could also explore the other HTML5 history API methods like history.replaceState()
However, none of this is probably best practice - I would think your best bet would be to let the querystring remain intact, but only trigger the Alert box / reset on the AJAX return if a password is set correctly.
In other words, have your reset handler return a readable response returning proper headers (eg 200 for success, 4xx for fail, etc), and adjust your $.ajax() call to something more like:
$.ajax({
url: your_url,
data: your_data,
type: 'POST',
success: function(e) {
// Password was reset
// ...show your alert
},
error: function(e) {
// Code wasn't found or reset failed
// ...do nothing or show an error
}
});

Browser refresh sends the last $http call made

AngularJS 1.2.13
var httpdelete = $http.delete("/api/categories/" + id);
httpdelete.success(function(data){
alert("Success");
});
httpdelete.error(function(data, status, header, config){
alert("Error!");
});
I do an asynchronous $http.delete request
The success callback function is executed and the alert box "success" appears.
I hit the browser refresh button
The $http.delete line is not executed (debugged with break points). Instead the error callback function is immedialy executed. The alert box "error" appears. No request made it to the server after clicking on the browser's refresh button
I was expecting the entire page to reload when I hit the browser's refresh button.
Instead, AngularJS seems to attempt to resend my last delete query without having to execute $http.delete and goes straight to the error callback.
How can I restore the natural behaviour of the browser's refresh button? I want it to reload the entire page and not attempt to resend the last asynchronous http request.
Open the network tab of the chrome dev tools. Load your page and hit F5. If you don't see a get to your index.html (or whatever your base url is), it's because angular handled it. If you do see the get, the you have rebooted the app for real.
Once you know which one it is, you can investigate further. Setting a breakpoint in the httpdelete callback and inspecting the callstack might also help.
Okay so here is what happened, my backend Nodejs+Express+MongoDB delete action was not returning anything to the client (browser). I didn't think it was necessary to return any information after deleting the document from mongodb.
The side effect of that is as I described in the original post. After deleting the document on the server, if a user refreshes the page using the browser refresh button then the page is not refreshed. Instead the $http.delete request is resent to the server and on top of it the error callback is executed.
After modifying my server side action and make it return a json document such as { success: true, message: "" } after a delete request, the browser's refresh button behaves as it should have which is to reload the entire single application page index.html.

loading effect in java

I have two jsp pages and one servlet. When user clicks submit button then processing is done in servlet and then result goes to another jsp page so that user sees his result. But I want to show a loading gif so that that gif will run till user gets his result and if in the mid time user stops that browser from loading then automatically that gif will also stop, how to do it?? In javascript or other only user will see that gif picture but when user will stop browser's processing still that gif is running which should not happen. How can i resolve this??
index.jsp---------------goes to a servlet------------result.jsp
Since all of this is going to happen in the user's browser, the solution cannot be in Java, it will have to be JavaScript, reacting to the onabort event.
As for stopping a GIF animation, that's not really possible (except perhaps through nasty hacks). I suggest using JavaScript (e.g. jQuery builtins or plugins) to do the animation as well.
Update: On second thought, why do you think you need to do anything at all? If the browser aborths the loading, it's their own fault, and the browser already has a loading animation that does exactly what you want. Why duplicate that?
That's nothing Java specific since everything will happen in the browser. You might need some JavaScript to open up that popup before the request is issued and register an event handler that closes the popup on window.onabort.
Try this
function doWork() {
//start loading gif
$.ajax({
'type': 'POST',
'cache': false,
'contentType': 'application/x-www-form-urlencoded; charset=UTF-8',
'url': #your_servlet_url#,
'data': $('form#' + #your_form_id#).serialize(),
success: function (data) {//data can be json or plain HTML depending on your scenario
// stop the loading gif
//redirect to result.jsp if you need to redirect user to completely new page with 'data' received
// or just send the result.jsp with processed data from the servlet and load the content 'data'
// received above in some div on index.jsp
},
error: function (xhr, status, err) {
//request cancelled by user or due to any other reason such timeout
if (xhr.status == 0) {
//stop the loading gif
}
// you can handle other errors(401,403 etc) too by examining xhr, status and err objects
}
});
}
Two things I can think of:
on submit simply show the gif. All browsers I have checked will not change the current page until the result from the second one is received.
use ajax (jQuery) to show the results. Then you can use an ajax activity indicator
The jQuery JavaScript library probably can provide some nice in progress effect.
For the future: HTML5 has a progressbar or such.
Use of Ajax might make sence (callback when loaded say inside DIV).
A very crude solution would be to use ajax for your form submit. You can display a loading gif on submit and as soon as you receive a response update the page and remove the gif.
Jquery ajax method would be able to handle abort by user, which would enable you to write logic to remove the gif for instance(or any other processing on page in case of abort)
Other possibility is if you use frameworks like struts(2.0). This gives a wait and execute interceptor especially for this kind of purpose(display an intermediate page while request is processed)

Categories