I was wondering if there is a way to get the URL of the returned resource after a AJAX call in JavaScript?
I want to use this with a form, which is in "mysite.com/users/add.html". This is a Spring MVC controller. If the validation of the form fails the controller will return the "users/add" view, but if the validation is OK it will do a redirect to "mysite.com/users/index.html", using
return new ModelAndView(new RedirectView("/users/index.html"));
Is there a way in JavaScript to find the URL of the returned page?
Thanks,
Stian
Solved this by setting the response header "Location" in a Java Filter.
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String path = httpRequest.getRequestURI();
httpResponse.setHeader("Location", path);
In JavaScript I could then use
XMLHttpRequest.getResponseHeader("Location")
Hopefully this won't cause any unforeseen problems. :P
If anyone else have an easier solution though I'd like to see it.
Related
I need to implement a requirement, where I need to deliver javascript code securely. My Idea is,
I will make the path as /something.js and in the controller, I will check the authentication, if not authenticate I will deliver console.error("Auth Failed").
How I can achieve the above scenario.
this is the simplest way using common request handler. works 100 %
#GetMapping(value = "/hello.js")
public void resources( HttpServletRequest httpRequest,
HttpServletResponse httpResponse) throws Exception {
//Authentication goes here or using handler interceptor
httpResponse.setContentType("text/javascript");
httpResponse.setHeader("MIME-type", "text/javascript");
httpResponse.getWriter().write(" function alertMan(msg) { \n alert(\"message:\"+msg); \n } ");
}
I have the following function that makes a request:
function postIngredient(action, options) {
var xhr = new XMLHttpRequest();
xhr.open(options.method, action, true);
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
xhr.setRequestHeader(options.security.header, options.security.token);
// send the collected data as JSON
xhr.send(JSON.stringify(options.params));
xhr.onloadend = function () {
// done
};
}
The function triggers a method on the server that basically returns a ModelAndView object:
...
ModelAndView mav = new ModelAndView("redirect:/recipies/edit?id=1");
....
return mav;
After the post request is successfully done the following GET request is done:
So in the 'Preview' tab of the request I have the correct page where it should redirect, but there is no redirection in the browser. The page remains the same where the postIngredient() function was initialy called. How then could the redirect be made?
You are making an ajax request via the XMLHttpRequest object from Javascript. This request is answered with a redirect and the XMLHttpRequest object follows the redirect, calls the edit and then the result of that (the complete page content for the edit page) is sent to your xhr.onloadend() method. The browser window itself is not involved in that and does not know that a redirect was sent internally.
If you want to keep the post as an xhr request and do not switch to a standard form-post you might change your post processing method to just return a String:
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ResponseBody;
#ResponseBody
public ResponseEntity<String> myPostProcessingIngredientsMethod(..put args here...) {
... do something ...
return new ResponseEntity<>("/recipies/edit?id=1", HttpStatus.OK));
}
Then in your Javascript code where you do the xhr request, get the result string from the resultdata and redirect your browser with something like
window.location.href = dataFromResult;
The #ResponseBody annotation prevents Spring from interpreting the returned String as a view name and wrapping the String in a ResponseEntity gives you the possibility to return erroor codes if something goes wrong.
When running an angularjs application, the user access may be withdrawn from the server side. In this case, every request results in a http 302 redirect and a login html (no partial) page. Since angular does expect whatever it was requesting in case the access would still be given, it breaks as it may expect a json string but gets the html login page.
Is there anything I can do do catch this event (listen to redirects, figure out whether html is returned, etc) and do a "hard" refresh of the redirect url?
Since you can't interfere an ajax 302 response and redirect to an error page, you will need to be a little creative.
You can add a header or a different response code to your relevant responses and add an interceptor on the client end.
The interceptor is a module that every ajax request\response goes throught.
You can add code that will look for that header and simple perform a $window.location.href to the login page.
Read here about interceptors.
Check this example out - It handles 401 responses.
If I get you right you are talking about the $http Service from AngularJS.
If thats the point, you could transform the response by yourself and check if its valide JSON like this:
$http({
url: '...',
method: 'GET',
transformResponse: function (reponse) {
var ret = [];//if the return stays empty, the repsonse may be HTML
try {
ret = JSON.parse(reponse);
} catch (error) {
//here you could check for the error
}
return ret;
}
}).success(function(answer){
if(answer.length === 0){//its empty, so its probably HTML
$window.location.reload();//refresh page here
return;
}
//its JSON with content!
});
I've got a requirement where we need to redirect to a page for JSF 1.2 Ajax call. In our case, we need to redirect to session expired page when the ajax call get fired after the session got expired. We are implementing the session expiry check in a filter and the invocation of httpservletresponse.sendRedirect is redirecting correctly to the session expired page as expected, but the url is not getting changed which is the issue now.
Any hints/soultion either at the client/server side is highly appreciated.
~Ragesh
Finally I managed to find a solution for the above problem.
In the filter, I set the response header "Location" and another custom header which I'll use in the client side to filter the response.
Filter code:
httpServletResponse.setStatus(HttpServletResponse.SC_OK);
httpServletResponse.setHeader("x-timeout-status", "true");
httpServletResponse.setHeader("Location", httpServletResponse
.encodeRedirectURL(sessionexpiryurl));
Richfaces have got a javascript file with various callbacks required during the AJAX call invocation which is packed inside the Richfaces libraries. There is one callback function called "processResponse" which will get invoked upon receiving response for all AJAX call initiated by JSF Ajax components . I've made use of this to handle the redirection functionality.
JS code:
var originalAjaxProcessResponse = A4J.AJAX.processResponse;
A4J.AJAX.processResponse = function(req) {
if (req.getResponseHeader('x-timeout-Status') != undefined && req.getResponseHeader('x-timeout-status') == 'true') {
window.location.href = req.getResponseHeader('Location');
} else {
originalAjaxProcessResponse(req);
}
}
Here we are overriding the method to handle our specific case and delegate the rest of the ajax call response handling to the in-built processing provided by richfaces.
Please let me know if you see any limitation to this solution or have a better solution to this problem
~Ragesh
I am facing very strange issue here. I have a servlet running on my machine which renders my web page based on some input parameters.
Now, my screen capture with PhantomJS is not working if I try to send my data as a JSON object as a POST request type. For e.g. if I try:
Client side
var data = {"op": "get"};
page.open(address, 'POST', data, function (status) {
if (status !== 'success') {
console.log('[ERROR] :: Unable to fetch the address - ' + address + ", with data - " + data);
phantom.exit();
} else {
page.render(output);
}
console.log('processing...');
});
Server side
Now, on the server side, I am using Apache Velocity View templating so I have a single method which handles both get and post like :
public Template handleRequest(HttpServletRequest request, HttpServletResponse response,
Context context){
System.out.println(request.getParameter("op"));
//Always null
}
However, if I try sending my data from phantomjs as:
var data = "op=get&..."
It works
Also, at many places elsewhere in my code..I am doing Ajax POST requests to the same servlet and it works perfectly for all those request.
Would anybody explain why my servlet is not reading the JSON parameters passed from Phantomjs?
Servlets deal with simple request, so they only know how to parse (natively) HTTP parameters, either GET parameters from the URL, or POST parameters sent as application/x-www-form-urlencoded. Newer versions of the Servlet specification can also read multipart/form-data.
But there's nothing about JSON mentioned either in the Servlet or the HTTP specifications. So you must use a library that knows how to parse JSON and make the resulting object available in the Velocity context.