I am developing a one page app with a lot of ajax interaction using the post method. When the server session times out the web page remains interactive with client script but the server calls fail silently. I would like to detect the timeout and then alert the client using some script already on the client.
My client functions calling the server use the $.globalEval(data) method and looks like this
When the server times out it returns the following which I can access through firebug.
I have attempted to identify the timeout using the .error() method on the jqXHR Object with no success, as there is no error.
Is there a neat way of doing this?
when in doubt put it in parenthesis and stick a dollar sign in front of it, only good can come from this.
marten kay wrote:
I'm using form based authentication out of the box, so as I understand the Container replies with login page, and I'm not sure how I intercept that?
You can't. For one thing, the architecture of the J2EE security system isolates the login process completely from the application. If you wanted to switch from FORM-based authentication to BASIC authentication, no program logic changes apply - you just change the setting in web.xml.
Servlets don't timeout. That's because HTTP is not a fully-conversational client/server protocol where you'd connect, chat back and forth, and finally hang up. In HTTP, the end of each servlet response causes the server to disconnect and no further communication will ever be done unless the client makes another request, when the cycle repeats itself.
Sessions timeout. However, every URL request you make causes the session timeout clock to be reset to the beginning. So you can't "poll for timeout" on a session. AJAX requests are URL requests, so they, too reset the session timeout clock.
An IDE is no substitute for an Intelligent Developer.
The scenario is that the user interacts with the page on the client, most interactions use functions loaded to the client on load, for other interactions an asynchronos call is made to server, such as to save content on the server. So if a user comes back to the page after being away for a while and the session has timed out, the server no longer sends back the required content and the page just sits there. My preference would be for the user to be redirected to a login screen when this happens.
As you say I can't change the behaviour of the container, and the best solution probably is to
sensitize the jQuery to the fact that the user has timed out
So I need to figure out a way of detecting that the session has timed out, perhaps by saying, if the server returns
then make a get to the login page. But this does not seem elegant.
I will see if there is anything in the headers sent back to client that client can access and use to determine if it is logged out.
Could you not write a Filter which only intercepts AJAX requests (either by looking for a parameter e.g ajax=true or extension e.g. /page.ajax) and check to see whether the current HttpSession is valid using HttpServletRequest isRequestedSessionIdValid() and if it is not valid send back an error code, otherwise allow it to continue?
[Edit: ah I'm not sure that would work using container authentication, sorry]
1. No, you can't use a servlet filter. The container intercepts the URL first, and if it doesn't like it, the app (and servlet filter) never get informed at all.
2. While it might be possible to scan for AJAX signatures, there's no standard "I'm an AJAX" call info. What I did in one app, however, was use AJAX-REST and pass an "ajax=true" parameter to the responding servlet.
3. You CANNOT explicitly request the login page via a URL. If you try, you'll simply get a page that won't submit properly. So if your AJAX client detects a logged-out condition, what it needs to do is forward to a protected page - any protected page. If you have a protected application Home page (or alternate URL to the Home page that's protected), that's a good one to use.
Another alternative is to forward to an error-reporting page, which can then have a login button/link that references a protected URL.
Not only does security allow it, it encourages it. In fact, certain custom headers such as content-type have their own special JSP directives. I'd have to RTFM to get the exact syntax.
Just make sure that the headers are declared before any of the HTML, because once you start sending HTML, you'll get an InvalidStateException. All headers go out before any content.
It's not especially kludgy to be scanning for the j_security_check, since it's always in login pages, and never useful for anything else. Just usually a little more convenient/efficient to look at headers than scan the page content.