I'm using $.post()
to call a servlet using Ajax and then using the resulting HTML fragment to replace a div
element in the user's current page. However, if the session times out, the server sends a redirect directive to send the user to the login page. In this case, jQuery is replacing the div
element with the contents of the login page, forcing the user's eyes to witness a rare scene indeed.
How can I manage a redirect directive from an Ajax call with jQuery 1.2.6?
No browsers handle 301 and 302 responses correctly. And in fact the standard even says they should handle them "transparently" which is a MASSIVE headache for Ajax Library vendors. In Ra-Ajax we were forced into using HTTP response status code 278 (just some "unused" success code) to handle transparently redirects from the server...
This really annoys me, and if someone here have some "pull" in W3C I would appreciate that you could let W3C know that we really need to handle 301 and 302 codes ourselves...! ;)
in the servlet you should put
response.setStatus(response.SC_MOVED_PERMANENTLY);
to send the '301' xmlHttp status you need for a redirection...and in the $.ajax function you should not use the
.toString()
function..., justif (xmlHttp.status == 301) { top.location.href = 'xxxx.jsp'; }
the problem is it is not very flexible, you can't decide where you want to redirect..
redirecting through the servlets should be the best way. but i still can not find the right way to do it.
Some might find the below useful:
I wanted clients to be redirected to the login page for any rest-action that is sent without an authorization token. Since all of my rest-actions are Ajax based, I needed a good generic way to redirect to the login page instead of handling the Ajax success function.
This is what I've done:
On any Ajax request my server will return a Json 200 response "NEED TO AUTHENTICATE" (if the client needs to authenticate).
Simple example in Java (server side):
In my Javascript I've added the following code:
And that's about it.
I resolved this issue like this:
Add a middleware to process response, if it is a redirect for an ajax request, change the response to a normal response with the redirect url.
Then in ajaxComplete, if the response contains redirect, it must be a redirect, so change the browser's location.
Putting together what Vladimir Prudnikov and Thomas Hansen said:
This makes the browser treat the response as a success, and hand it to your Javascript.
I got a working solulion using the answers from @John and @Arpad link and @RobWinch link
I use Spring Security 3.2.9 and jQuery 1.10.2.
Extend Spring's class to cause 4XX response only from AJAX requests:
applicationContext-security.xml
In my JSPs, add a global AJAX error handler as shown here
Also, remove existing error handlers from AJAX calls in JSP pages:
I hope it helps others.
Update1 I found that I needed to add the option (always-use-default-target="true") to the form-login config. This was needed since after an AJAX request gets redirected to the login page (due to expired session), Spring remembers the previous AJAX request and auto redirects to it after login. This causes the returned JSON to be displayed on the browser page. Of course, not what I want.
Update2 Instead of using
always-use-default-target="true"
, use @RobWinch example of blocking AJAX requests from the requstCache. This allows normal links to be redirected to their original target after login, but AJAX go to the home page after login.