I've got an issue that occurs eventually in my website. It uses AJAX requests to get data from the server, which uses Spring MVC.
What happens (intermittently) is that sometimes we got an exception like this one:
org.springframework.web.bind.MissingServletRequestParameterException: Required Integer parameter 'page' is not present
at
This kind of exception occurs in some AJAX POST calls (not only for this case!!) and we still cannot reproduce it to understand what is happening.
For example, in one of the cases the parameter 'page' (used to load content while the user scrolls the page - so it's a required variable) is being sent through an AJAX call that has a 'data' field with the page parameter coming from a form like this:
<input type="hidden" name="page" id="page" value="1">
And a ajax call like this one (both $("#filter") and url are ok):
$.ajax({
type: "POST",
data: $("#filter").serialize(), // serializes the form's elements.
url: _ctx + URL_FILTER,
cache: false
})
The only way we got to reproduce that is by changing its property 'name' to something other than "page". But I guess this is not the case (most users don't even open the developer console...)
I've googled it a lot and I checked every possibility. The enconding is ok:
(Content-Type: application/x-www-form-urlencoded; charset=UTF-8)
The parameters are ok, the AJAX looks ok, everything seems ok... But we cannot find what is going on. We have tried a lot of possibilities but we still couldn't force these exceptions to happen.
One hypothesis we have is that sometimes the AJAX may send empty data blocks, with none of the parameters. But we don't even know whether it's true or not and how to check its veracity.
What are the possibilities? How can it be tested?
EDIT:
We could reproduce one of the ways to get the Exception: Reloading the page repeatedly for some seconds (keeping the reload key pressed for a while). Is there a way to prevent the exception for this case?!
Make the below change to controller's class method for page parameter
#RequestParam(defaultValue = 0) int page.
Or paste the controller method here.
If you are not been able to figure out what is reason behind missing parameter, so you can add
public void controllerMethodName (#RequestParam(required = false) int page)
code in your controller definition which will not throw any exception if parameter is not present in your ajax request.
Are you sure your form isn't being modified at the same time? For example, if your library used to handle the scrolling of the page tries to send the same form in a very short time (the first call updates the form while the second call is serializing it). This might be only on some browsers, not all of them, given that you can't easily reproduce it.
The way data is put back in the form might also be responsible for your problem.
Logging HTTP requests / using analytics would help you identify which requests / user agents are causing issues.
Related
What would be the "best" approach to dealing with forms which have to work without and with JavaScript enabled?
Would it be better to create different routes for each, like
AJAX request: route "API/contact" and return res.send("message")
without JavaScript: route "contact"and return a redirect with a query param of "message"
Or in one route and detect xhr and render it depending on this?
Or is there a better way of dealing with the problem of taking the user to the res.send("") when the JavaScript isn't enabled to give the user feedback on the submit?
To clarify:
I have a site which is working with AJAX requests for its forms to avoid full page loads. It lacks the fallback when JavaScript is not enabled and thus when a user clicks submit on a form, he receives the data from the post back with res.send and it replaces the whole page, instead of the desired effect which would be to just update a label with the "success/fail" message. The question then remains as above which would be the neat way of dealing with this?
Probably the best thing to do would be to check the X-Requested-With header and check that it contains XMLHttpRequest (but this might get deprecated as the new fetch API will slowly come into browser.
Based on that value, you might want to return a JSON payload, or eventually trigger a server side rendering, therefore returning an HTML page ready-to-be-consumed.
As an alternative, you can return a redirect response with a particular query string value; once the page is loaded, you will check for that value (using qs for example, or deparam in jquery and manipulate the client side accordingly.
Your server routes have nothing to do with client-side javascript. You don't need javascript to receive a "res.send" message.
I'm trying to update a resource's attribute via AJAX (using PUT or PATCH request) and the request is getting fired multiple times.
I'm using Angular JS and jQuery.
HTML Template
Here is how my HTML Template looks like -
<span id="test" ng-click="setValue('test')"></span>
Javascript Code
Here is how my Angular JS code looks like -
$scope.setValue = function(value){
$.ajax({
method: 'PATCH' // or PUT,
url: 'resources/' + $scope.resourceId,
data: {
test: value
}
}).success(function(response){
console.log(response);
});
};
Rails Code
Here is how my controller's update method looks like -
def update
#resource.update(resource_params)
respond_with(#resource)
end
Screenshots
The AJAX request gets fired several times (close to 15 times). See screenshot below -
By simply changing the PATCH (or PUT) request to POST, the call gets fired only one. See screenshot below -
Is there any reason why the PUT requests are getting fired multiple times, while the POST request gets fired only once?
Even though the PUT request updates the value correctly. I'd like to prevent it from being fired multiple times. Is there any way to do that? (Without changing the routes or controller methods)
First thing to note: your screenshot from your POST request is returning 404, most likely because you're not updating your controller action to be a create instead of an `update. (Make sure that your routes are set up to match as well). Since there's no action, Rails returns a 404, and it will stop processing.
This is important, because your PATCH screenshot looks like it's probably infinitely redirecting to itself. Each PATCH request is getting an HTTP 302 Redirect in response, and since you're getting a lot of them, my guess is that it's redirecting to itself (either the same URL, or a URL that redirects to the same controller method... or some other middleware that's causing a redirect for any URL).
So, if you changed your controller action and route to allow for a POST, I bet you'd get the same multiple requests & redirects that you get with a PATCH.
That solves the one mystery. The next is to ask why you're getting the infinite redirects. I can't answer that from the available information, but this might get you started on a solution.
So I am trying to write a script that will go out and edit the html for all of my tumblr blogs, so i dont have to do it manually.
The problem is that tumblr doesnt really have a form that i can edit, and then submit through JS.. they have a very strange way of compiling the custom html and submitting an ajax request.
So, i was wondering if there was a way to intercept the ajax call before it goes out, edit a field in the data, and then make the submission my self?
I tried something like this:
var submitted = false
$("body").ajaxSuccess(function(evt, request, settings){
j = $.parseJSON(settings.data)
j.custom_theme = "PUT HTML HERE"
if (!submitted)
$.post(settings.url, j, function(data){
console.log(data);
submitted = true;
})
})
But i got a 403 forbidden error.
Does anyone have any ideas?
I'm not sure exactly what you're trying to do, but must this be done with a custom script? It sounds like this will only be used by you, so an extension should work. If so, there is a very useful Firefox extension, in the spirit of Firebug, called Tamper Data. This should be able to do what you want.
It allows you to monitor each request made by the browser, and you can turn on an option that allows you to look at, and edit, every single request before it gets sent.
Well, it's pretty obvious that ajaxSuccess isn't going to work in the way you want it to.
Assign the function which sends the AJAX request a new name and overwrite it. Call the previous function at the end of the new function, i.e. after manipulating the data the way you want.
I am working on a MVC project that is supposed to have one page only, with two zones. On one zone I have a Google Map with markers, and the second zone is populated with the selected marker's details.
The details view has a button that when clicked should change the entire view into edit mode without refreshing the page or redirecting it. I have used two views, for details and edit and with the help of ajaxForm function I am switching back and forth between these two views. I'm adding the ajaxForm on documentready for edit view.
<script type="text/javascript">
// wait for the DOM to be loaded
$(document).ready(function() {
// bind 'myForm' and provide a simple callback function
$('#currentDiv').ajaxForm(function(data) {
$('#currentDiv').html(data);
});
});
</script>
The problem appears when on server-side an error appears while trying to save data from edit view and I want to return to the same edit view with the errors displayed. The ajaxForm handler is not added any more and even if the new values that will try to be saved are ok, the detail view is loaded in another page.
Unfortunately, the use of ajaxForm creates some other problems because I don't have control over the cases when the ajax call fails.
Any ideas on how could I fix this? Is it some other solution to switch between those two views without using ajaxForm and without refreshing the page?
I think there are a couple of different questions that you are asking.
First off, you add jquery handlers to deal with the case when you get a 500 type error from the server.
Something like the following. I suggest taking a look at the docs for more info.
$(document).ajaxError(function(event,jqXHR,ajaxSettings,thrownError){
if (jqXHR.status != 0){
window.location = <error page>
}
}
The second problem seems to stem around error handling of known errors (say invalid input). In this case I suggest the following workflow.
1) User clicks on edit button, taken to edit screen
2) User enters in data, use client side validation to do initial check
3) User submits, user is then taken to the view screen and is shown a
success or error message.
The server response could look like:
public ActionResult Edit(EditModel model){
if (!ModelState.IsValid)
{
return Json(new {successful = false, message = "Failed.."});
}
...
}
On the client side, your form callback should now handle the message and the fact it was successful or not. In my implementation, I used knockoutjs to create a "message" area that I could update and clear. (I created templates, etc).
Remember to use client side validation for the easy field validation stuff.... This will save a trip back to the server.
Yours could be quite simple, by popping up the message returned from the server.
Lastly, document ready only fires when the original document is done loading, never again for an ajax call (at least that is my understanding). Just put that code that is the document.ready at the bottom of the edit page. It will fire after the html it is targeting has already been rendered.
Hope that helps!
I have begun to move away from the asp.net views available in ASP.Net MVC due to some incompatibilities and/or unnecessary complexities when trying to achieve functionalities expected of AJAX enabled sites of the day.
I would recommend moving towards a design where you use "dumb" HTML files, use jQuery to download them using AJAX and drop them into a container (personally I use a div) and then use another AJAX call to gather the data from a controller. There are a number of advantages to this approach:
It establishes a real (not fake) separation between client side and server side code.
Html files can be cached on the client cutting down on the amount of data transmitted.
Binding of the Html elements becomes a client side task achieved using jQuery offloading processing cycles from the server.
Controllers essentially become collections of web methods which means they can be untilized by iPhone and Android apps making mobile deployment easier.
I realize this probably isn't the exact answer you're looking for and this may not be an option for you but my hope is that it will help someone at some point make a decision to move away from mixing HTML and server side code.
I've written some HTML/Javascript that sits on a third-party server for security reasons. This page performs a javascript post to another page on the same site. However, instead of responding with useful data, it instead wants to perform a redirect (if you would post via a normal HTML form to this page, it would redirect your browser). How can I process this process? I basically want to be able to extract the url's query parameters that it is trying to redirect with (and then put this link into a hidden form field).
Here is my basic ajax post...
$.ajax({
url: '/someurl/idontcontrol',
data: serialized_form_data,
async: false,
type: 'POST',
success: function(data, textStatus, x) {
alert(x);
alert(x.getAllResponseHeaders());
return false;
$('#redirect_link').val(WHAT_DO_I_PUT_HERE);
}
});
Note that the URL I am posting to is not one that I control, so I have no power over what it returns.
UPDATE: When I use the above alerts, I receive "[object XMLHttpRequest]" and "null". I'm monitoring the headers with a Firefox plugin and they seem be coming back as expected, but I can't seem to access them via javascript (I've also tried x.getResponseHeader('Location'), but that and all other calls to getResponseHeader return empty).
ALSO: I don't know if it matters, but the status code is 302 (as opposed to 301 or 303).
Thanks!
According to the jQuery Documentation the success method can take a third argument which is the XMLHttpRequest object.
According to Mozilla's XMLHttpRequest page, this object should have a "status" property. If you check the value of this property, and it is a redirect code, such as 301 (permanent redirect) or 303 (temporary redirect) it is known the processing page is trying to perform a redirect. The "statusText" property should be able to be used to determine the location it is trying to redirect you to.
If you know it is trying to redirect, you can then re-post the data through Ajax to the new URL.
The strange thing is though, when researching this, stumbled across this page that indicates the XMLHttpRequest object should follow redirects (see the comments). So it seems like this would be a non-issue.
Unless the processing page is using an HTML meta redirect (like below) to do the redirection. In that case, I'm not sure what could be done - maybe try to parse the returned HTML for meta tags and see if any of them are attempting a redirect.
<meta http-equiv="refresh" content="0;url=http://www.example.com/some-redirected-page">
You can't get the full HTTP headers from an AJAX call in JQUery, so you can't process the redirect in this way.
However with a raw javascript request you do have access to the XMLHttpRequest getAllResponseHeaders() method which will allow you to process the redirect (this function for single headers).
Sorry, not directly an answer to your question, but I'm sure it's possible with jQuery too as it's quite simple with Prototype.
// Warning: this is Prototype, not jQuery ;-)
//...
onComplete: function(response) {
var refresh = response.getResponseHeader("Refresh");
var whatever = response.getResponseHeader("Whatever");
}
//...