The jQuery load function is nice but how do you handle session timeouts?
I used it to add new content into a div but if my session times out, the login screen appears in that div instead of in the complete page.
Is there any way to handle this?
I am using it in JSP pages.
Should I replace it all by jsp:include pages and refresh the page every time I need to adjust the page or is there a way to do this with the jQuery load function and handle session timeouts properly?
I have tried validating the session before the call, but since there isn't any call to the server, the session still seems valid until the load request finds out it has expired.
So session is not null in the current page, but when the load is executed to retreive the other page, it will get the login page instead.
I suppose your login page is a redirect. Then you can use the complete callback (third parameter, see doc) to check the response.
I encountered the same problem, and resolved it. So I am going to share my own answer.
At first I wanted to check if the response code is 301, but you cannot catch 301 redirect in the complete callback. It just throws 200, which is the result of redirection.
So I, instead, read the xhr.responseText and check if it starts with "<html>". Because if it is, it means that the response contains redirected login page instead of the modal contents.
$(".modal-wrapper").load("/modal" + e, function(response, status, xhr){
if (xhr.responseText.trim().startsWith("<html>")) {
console.log("redirect to login page");
window.location.href = "/";
}
});
Actually, instead of window.location.href = "/";, what I wanted to do is, document.write(xhr.responseText); so that the unnecessary request could not be made. But I counldn't achieve this due to some UI problems ;P
Related
I have a simple SPA used by our team, using angular1. It gets most of its data from REST calls, but I also have a "meta refresh" tag to occasionally reload the whole page, to make sure the user gets occasional small functionality changes. There is no need to ever make this optional, it should just reload the page.
The minor annoyance with this strategy is that when the user sometimes disconnects from the network (traveling between work and home, for instance), the page reload fails, and it gets into an error state. It's easy enough to just force reload the page, but I'd like for this to be a little cleaner, such that it only reloads the page if it can reach the page.
I noticed the advice at https://davidwalsh.name/meta-refresh-javascript . That uses javascript to do the reload, but it's not conditional on the page existing.
Is there a reasonable variation of this that will simply skip the reload when it can't reach the page, and then reload again when it can?
The navigator object has a property online that you could check
if(window.navigator.online){
window.location.reload();
}
Or make an ajax head request first and if that succeeds do the refresh
For my needs, I ended up implementing a "heartbeat" method in my controller, which calls a Heartbeat service, which does a HEAD request to my REST service, and returns true if the status is 200.
I then call this from the HTML like this:
<script type="text/javascript">
window.setInterval(function() {
// Call controller method to call heartbeat service.
if (angular.element(document.body).scope().heartbeat()) {
window.location.reload();
}
}, 900000)
</script>
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
}
});
I have the following js function that sends a post request back to the main index page. This script is working in Chrome but is not sending any parameters in firefox while still posting back to the page. I am verifying this via the network tab after inspecting the page in firefox.
function addDrive(ans){
$.post("index.php", {add_drive: ans });
location.reload();
}
This function is called via a onClick on a button I have placed on my page:
<button onClick="addDrive('y')">Add Drive</button>
I have used similar functions in the past that have worked for both firefox and chrome and I just cant figure out why this does not work in firefox.
My suggestion would be doing something like this :
function addDrive(ans) {
$.post("index.php", {add_drive: ans}).then(function() {
location.reload();
});
}
This would ensure that you reload the page only after successfully finishing the post request. You could also provide a success handler instead if you prefer that instead of using this promises API. You could also do the same in an always handler to ensure it reloads the page even if the request fails but that would be subjective to your requirements.
However, I would argue that this doesn't look like good practice at all, if you have to reload the page you could just have a form and post that instead of trying to post using the jquery handler. You could do something like form.submit() in javascript and that would submit the form and it would submit the data in the form by a post request as long as the method on the form is set to 'POST', that way you don't have to reload the page manually and you can do that from the server end.
Try to reload your page after successful post:
$.post("index.php", {add_drive: ans}).done(function( data ) {
location.reload();
});
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.
I have a members site. Every web page's header bar will have the following 2 options depending the user is logged in or not:
Option 1) if the user is logged in, it will have the following 2 links:
"user12345"
"logout"
Option 2) if the user is log out, above 2 links will become:
"login"
"register"
The page has some Javascript code which will check a user cookie. If the user cookie exists, if will display option 1), otherwise option 2). There is no problem with the Javascript. It shows above options correctly.
Here's the problem. I use a server side script (perl) to do the "logout" function. The script will delete the cookie and re-direct back to the original page. I am hoping the page will show option 2), but it doesn't. It still shows option 1). The page needs to be refreshed to show option 2). This is confusing because users have clicked the logout link, yet when they return to the page, they still see their usernames there. They need to refresh the web browser in order to see that they have logged out.
Option 2) should show on the page upon clicking the "logout" link. But I simply have no idea how to get this done successfully.
Please provide your expertise to fix this problem.
First, I would suggest breaking the problem down so that you can test the logout functionality separate from the page redirect.
Modify your Perl script so logout doesn't redirect.
Login and then click logout.
Use a Chrome or Firefox extension that lets you view cookies. Verify that the cookie has been deleted.
If everything checks out here, I would suggest that you then reconnect the redirect and repeat the above steps:
When your page redirects and you don't see the login | register buttons, check to see if the cookie was deleted, if the cookie appears, then there may be something being cached in the code after the redirect.
As an alternative, you could use the document.referrer to capture your logout URL in your JavaScript code and also use this to determine if you should show the login | register buttons. For instance:
if(document.referrer = "/logout" || /* existing check of cookie goes here */) {
// show login | register
} else {
// show username, etc.
}
If possible, the best solution usability-wise would be to turn your logout url into an AJAX call so you don't need to reload the page. This would be better than the above solution because you could check the response object to determine if the logout operation was a success. If so, you could then dynamically replace the header bar with the correct text.
An AJAX example, using jQuery.ajax, is as follows:
$.ajax({
url: '/logout',
success: function(data) {
if(data.logout == true) {
// user is logged out
}
},
error: function(jqXHR, textStatus, errorThrown) {
/* problem with logout */
}
});
Your perl logout script will need to return a JSON object as a String, if successful:
{"logout":true}
There are other ways of making AJAX calls and transferring data to/from the server, and you can find those examples doing a search on Stackoverflow for "AJAX".
BlockquoteFirst, I would suggest breaking the problem down so that you can test the logout functionality separate from the page redirect...
I've fixed the problem without the use of AJAX call.