Struts2 Ajax issue - ajax

The problem is the following. When user clicks on the link I load the data into a div, but when the session of the user is expired I need to redirect him to login page, or if the is external error I need to redirect the user to error page. The problem is, if for example my interceptor sees that the user is no longer in session and tries to redirect him to login page, the login page is again loaded in the div. the other elements on page remain. How can I make the page reload without JavaScript? I mean directly from struts.xml.

You need to send to your browser whether it is a new session or not.
One way.
In your interceptor add a header to indicate whether it is a new session. Then if you are using jquery you can bind the ajax complete and check the header for the attribute that its a new session. And finally on new session, do a location.reload.
your ajax for jquery would look something like this
jQuery(document).ajaxComplete(function(e, xhr, settings) {
var status = xhr.status;
if(status == 200 ){
var isAuth = xhr.getResponseHeader('_isnewsession');
if((isAuth == '1')){
alert('Your Session has timed out!');
location.reload();
}
}
});
Does that make sense?

Related

php redirect to another page in laravel

I have a modal view (the one from bootstrap) in the front end.
Upon clicking the submit button the user will be going to a function in controller:
Route::post('post_question', array('uses' => 'QuestionController#postQuestion'));
And at the end of the postQuestion i want to redirect to another page.
I tried:
return Redirect::to('mywebsite/question/1');
return Response::make( '', 302 )->header( 'Location', 'mywebsite/question/1' );
return Redirect::route('question/'.$question_id)->with("question",Question::find($question_id));
header("Location: mywebsite/question/$question_id");
none seem to work though.
The thing is, i can see the request in XHR but just that the page is not redirected.
Is the modal somehow blocking the behavior?
You can redirect with an AJAX request. However, you will find that the results will not be quite what you expected.
On a redirect, Laravel will should set your response code header as a redirect response and then the content of the redirected page would be sent.
You could do one of two things depending on how you wanted to handle things.
Send a JSON response back to the submitted form with a meta data parameter and then use this meta data in your success function to set window.location.
Your Laravel controller responding to the post would look a bit like this:
public function postQuestion()
{
// DO stuff to set your $question
return [
'question' => $question,
'meta' => [
'redirect_url' => url('mywebsite/question/'.$question->id),
'status' => '400',
// Any other meta data you may want to send
],
];
}
Then assuming you are doing some jQuery AJAX call, change your success callback (I'm calling it questionSubmitSuccess here):
questionSubmitSuccess = function (data) {
// Anything you may want to do before redirecting the user
if (data.meta.redirect_url) {
// This redirects the page
window.location = data.meta.redirect_url;
}
}
Continue redirecting from your controller and then do something a bit more similar to rails turbo links and replace the entire page with Javascript:
You can do this a few ways: using [Modify the URL without reloading the page browser History API), or using jQuery.load to submit your form.
The browser history API might work a bit easier as it would still allow you to handle response errors, but it only works in more modern browsers.
jQuery.load would likely require rewriting a bit of your AJAX submitting code and is harder to handle things like errors (it will replace your page content no matter the status code from what I can tell), but it has better browser support.
IMO, the first approach is a bit more maningful as the API endpoint is usable by something other than this single implementation.
Also, there are fewer points of failure and error states to manage compared to trying to replace your entire DOM without a page reload.
U can put button inside form and when u submit that button pass data from page to controller and from controller call the another page with that data
like return View::make('users.index,compact('data'));

How to prevent page navigation until ajax call is complete

So I have an ajax call to bring down several dozen chunks of data all several megabytes in size, afterward storing the data locally via the html5 filesystem api.
I wanted to prevent the user from navigating away from the page before the ajax calls were done. I decided to explore the onbeforeunload event, to have it notify that the user should stay on the page until the ajax calls are complete. I set the following before the AJAX call and at the end/success of the AJAX call I reset the window.onbeforeunload.
window.onbeforeunload = function(){
return "Information is still downloading, navigating away from or closing "+
"this page will stop the download of data";
}
When I attempted to close the page or navigate away from the page, the pop-up message comes up as expected informing the user to stay. However, once I confirm that I want to stay on the page, the ajax calls do not resume where they left off. Is there a way to prevent the ajax calls from pausing/stopping or to continue on/restart with their executions?
I'm open to any ideas to implement desired functionality described in the title of this post.
Pretty sure you can create a global in the .js file like...
var request;
Then assign your ajax call to this variable.
request = $.ajax{
//Ajax
//Stuff
//Goes
//Here
}
Now inside your window.unbeforeunload function, add this conditional statement.
window.onbeforeunload = function(){
if(!request){
return "Request not initiated";
}else{
//Request is in progress...
//You can use request.abort() if you need
}
}
EDIT: To elaborate on on some of the methods you can use on the request object, check out this page. (for example, .done or .always may suit your circumstances)

Page Navigation while Ajax call in progress

In our application we are making an ajax call on the final submit button and displaying a modal dialog with progress bar in it. After successful processing the dialog will be updated with the response. Now my requirement is to change the modal dialog to non dialog and allow the user to navigate to another page while the ajax call gets finished.
What are the implications if i change the modal window to non modal window. Will the ajax call still continues or will it get aborted. if it continues will it have reference to the dialog to update it with the response.
Please let me know your views.
Whatever you do while your AJAX call is being made in terms of maniuplating the view, will not impact the AJAX call itself. As long as you let the AJAX call complete and show the changes on the callback, you will be okay.
Needless to say, you cannot change the actual page your on but if I understand you right, your not doing that anyway.
A simple experiment to try the idea
I've written a simple example where I have a HTML page with a link to another page. When I click that link, it sends an AJAX request to a PHP script that simulates a long process (wait 10 seconds) and then changes a variable in the session. The target page then echoes that variable.
When I click that link, the page starts a long AJAX request but it also navigates to another page. The result is that the AJAX request is cancelled and the other page prints "nothing".
Here's the server.php:
session_start();
$x = isset($_SESSION['x']) ? $_SESSION['x'] : 0;
sleep(10); /* simulates long process */
$_SESSION['x'] = ++$x;
echo $x;
index.html (the significant portion):
Click here
The AJAX request in index.html (inside a <script> tag):
document.querySelector('a').onclick = function(e) {
var xhr = new XMLHttpRequest();
xhr.onload = function(e) {
console.log(JSON.parse(xhr.responseText));
}
xhr.open('POST', 'server.php');
xhr.send();
}
Possible solution
If your request is time consuming on the server only, create an endpoint that returns the progress of that process, then add a javascript code in all your pages to consume this endpoint and show the progress to your user.

Ajax submit redirect MVC 3

Although I read dozens of answers I could not find a solution.
I'm using MVC 3 with Razor. I have a simple Form with client validation via ajax. This part works fine. My problem is: In the update Action of my Controller I want to redirect to another Action. If the user disables Javacript, this works fine. But with javascript/ajax enabled, the redirectaction doesn't seem to work. Instead it looks like if some kind of partialview or something like that is executed.
My Controller/Action-code:
Function UpdateItem(Item As CItem) As ActionResult
' some validation code, save etc.
if everythingok then
Return RedirectToAction("Updatesuccess")
else
Return RedirectToAction("EditItem")
endif
End Function
My html page looks like (shortened/pseudo):
Logo image
H1
some text
<form>....</form>
When the form is submitted via ajax the new html code is added beyond "some text", so the form is replaced but everything above the replaced form stays on the page.
When ajax/javascript is disabled then after submit a whole new page is loaded. I checked the http headers and noticed, that with ajax there is no redirect (which is logical in some way because it is ajax).
What can I do? I want to redirect to a new page.
Is it possible to disable the ajax-submit and only use the "normal" form-submit?
I like the client validation via ajax while the user enters data and I want to use this, but for me it would be good enough, if the submit would be a "normal" submit.
I hope someone understands what I want and can help me.
Thanks.
I'm not a 100% sure I understand your question, but what the heck, don't downvote me :)
The problem is, redirect works via sending a HttpResponse with the redirect indicated in the headers, which the browser understands. If you submit via AJAX, it's not the browser that handles the request, it's your OWN JS code.
Here is the trick: instead of returning a redirect, return the Url (preferably as json), and then redirect manually using window.location.
I'm not fluent in VB, here is how I'd do it in C#:
var url = new UrlHelper(this.ControllerContext.RequestContext);
var link = url.Action("UpdateSuccess");
return Json(new {link});
and then in jQuery:
$.ajax({ method: 'POST',
url: 'your post url',
success: function(result) {window.location = result.link; },
// ... (passing form etc)
});

Problem with LogOn page loading inside div on membership redirection

I am using Membership Authentication in an MVC3 webapp. I make heavy use of jQuery and loading partial views inside divs and tabs. My problem is when the user has been inactive and is logged out and then he tries to call an Action inside a Controller which loads a partial view inside a div or tab, the entire page with the LogOn view is loaded inside the div, wrecking my layout.
The redirection is done correctly, and is the desired effect, however I would like the LogOn page to load on the window, rather than on a div in the current view. Does anyone knows how to accomplish this?
Is it clear what I want and whats wrong?
Thank you.
The combination of authenticated calls and Ajax is always a problem, because Ajax doesn't properly handle the redirect.
I prefer not to the the Authorize attribute on Ajax-called controller actions, but to check for the user being authenticated inside the method and returning a specific HTTP response (such as HTTP403 Unauthorised). Using an error handler in your client-side script, you can test for this response and redirect to the login page by setting window.location.
Just fixed my problem with a little script. Its not the best solution, and I am not totally comfortable with it, but at least it solves my problem in a very simple way.
In case anyone is interested, here its what I did, I added this snippet of code at the beginning of my Log on page:
<script type="text/javascript">
function funcName() {
var str = window.location.href;
var num = loc.indexOf('#Url.Action("Action", "Controller", new { area = "" })');
if (num < 0) {
window.location = '#Url.Action("Action", "Controller", new { area = "" })';
}
}
relocate();
</script>
This way if the login page loads inside some div and not on the window, it relocates to the actual login page.

Resources