Bizarre behavior with jQuery DELETE requests - javascript

I'm having a really strange issue interacting with a RESTful json interface and can't seem to get anywhere diagnosing it.
Using jQuery, I send a DELETE request to the JSON api and receive a 204 response. Success method is called. Everything is happy.
$.ajax({
type: "DELETE",
url: "/content_blocks/" + $(this).parent().attr('id'),
dataType: "json",
success: deleteItem($(this).parent())
});
From Firebug console:
> DELETE http://localhost:3000/content_blocks/228 204 No Content 92ms
Now I do the exact same thing with another item and get this:
> DELETE http://localhost:3000/content_blocks/231 (spinning circle loading forever)
The server sends the same response, jQuery fires the success callback. But the response is apparently never received.
If I send a third DELETE request, it works normally again, and apparently alternates this way forever.
I have another ajax call that sends a POST request. I do any number of these in a row with no issue. But if I do a successful DELETE first, then a POST, the POST behaves like the second, unsuccessful DELETE, except that the success method doesn't fire. If I do a second POST, that one works, just like the third DELETE.
To me this seems like something about the first DELETE request, even though it's successful, is broken or not getting properly reset. Somehow a second request resets it.
I'm using rails 4.1.0.rc1 and jQuery 1.11.0 if that makes any difference.
Has anyone seen anything like this before?
Could this be a jQuery bug?

Related

Rails - AJAX PUT or PATCH firing multiple times

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.

AngularJS 1.2 $http seems to cache POST requests when no data is passed

I'm having an issue with AngularJS 1.2 POST requests using $http service.
On a button click, I trigger a POST request like so:
$http.post('my/url').success(function(responseText) {
// Do something
console.log(responseText);
});
My problem is, if I click twice on the button and the first callback hasn't fired yet, only one HTTP request is issued, but my callback is fired twice (with the same data as a parameter).
If I explicitely add cache: false:
$http.post('my/url', {cache: false}).success(function(responseText) {
// Do something
console.log(responseText);
});
Then two requests are issued as I expected.
It looks like a bug to me. Why would anybody want to cache a POST request? Moreover, the AngularJS documentation specifies that we have to pass cache: true if we want to activate the cache for GET requests. Which sounds like it is inactive by default, and not active at all for POST requests (which would make sense to me).
Is there a way to deactivate the cache once and for all, for every request, on the 1.2 branch? I didn't find any.
EDIT
I misused $http.post. The second parameter is not the options map, but rather the data to send to the server. According to the documentation, this parameter is mandatory. So I can execute this:
$http.post('my/url', {'anything': 'anything'}).success(function(responseText) {
// Do something
console.log(responseText);
});
And it works as expected.
So the real question is: why is the data parameter mandatory for a $http.post call to work properly? I feel like I am missing something about HTTP. I already have everything I need in the URL (something like company/company_id/employee) and I don't need any additional data.

calling jQuery.ajax consecutively results in single callback

this is a interesting problem.
i am doing an asynchronous ajax put
return $.ajax({
url: url,
type: 'PUT',
contentType: 'application/json; charset=utf-8',
async: true, // default
success: function (result, textStatus, xhr) {...}
this works as expected, unless a user does a put before previous call returns (even though it's async, the call does take .5 second to complete)
if a user presses the button a few times (executing multiple puts) the following happens:
i see only one server call in fiddler
success gets fired for every click
all callbacks get the same new row ID (returned by the server)
this leads me to inevitable conclusion that the first server callback triggers all outstanding callbacks..
i could disable the button until the callback returns, but is it possible to handle multiple outstanding calls? is this a browser limitation? best way to handle this?
UPDATE
as a test i switched to using POST instead of PUT: adjusted type: 'POST' on JS side, and [HttpPost] on web api (server side).
the behavior did not change.
UPDATE
looking at posts like this one.. this really should work. i don't see any specific reason why the rest of concurrent requests are not not making it out to the server.
Shouldn't PUT requests be idempotent? That is, submitting multiple requests should generate the same response? If so, the code may simply be trying to coalesce your identical PUT requests since they should all end up with the same result. If you're incrementing some ID for every post (i.e. changing server state) then you should be using POST instead of PUT.
This may not fix your issue; it's just a thought.
You can't wait for an async callback in javascript. You have to restructure your code to do all future work based on the async response from the actual callback.
If you need to make multiple consecutive ajax calls, then you issue the first one and in the success handler or response handler for the first ajax call, you issue the second ajax call and in the response handler for the second one, you carry out whatever you want to do with the data

JSONP request callback

Ok, after an whole day trying to get this to work I just don't seem to know what's the deal with this, so here it goes:
I have a WebService hosted locally by now (http://localhost:15021/Service1.svc/[whatever_method]) and an HTML Page on a different file.
FYI, both WebService and HTML Page will get hosted on different servers.
I'm trying to get some info off the WebService to the HTML Page by the onload=load() method in the HTML Page.
My JavaScript code is:
function load() {
alert("Loading...");
$.ajax({
url: 'http://localhost:15021/Service1.svc/getAllNoticias',
type:'GET',
dataType: 'jsonp',
jsonp: 'loadNews_callBack'
});
}
function loadNews_callBack(result){
alert(result.data);
}
Additionally, the JSONP is loaded on the Page with an OK (200) status (As you can see here) which should (I guess) call the callback function, but it isn't.
What can I do to get around this? I already change the request parameters 500 times (e.g., added "?callback=? to the url, with or without jsonp attribute, etc...)
Any help would be great,
Thanks in Advance
Check the actual response text to verify that the response is correctly being wrapped by the callback function. It is possible that your service is not setup correctly to handle JSONP so it simply responding with JSON. It will still come back as 200, but fail to execute.
loadNews_callBack([json...])
vs
[json...]
See this question as reference on how to go about updating your service:
ASP.net MVC returning JSONP

How could my MVC JSON action be called with GET if my only use is with POST?

I have an ASP.NET MVC action that is returning JSON. The only place I am calling that action is from one page with this code:
$.ajax({
type: 'POST',
url: actionUrl,
dataType: 'json',
...
});
The page and this AJAX call are working fine from the user and testing perspective. However I found one error in the log saying:
This request has been blocked because sensitive information could be
disclosed to third party web sites when this is used in a GET request.
To allow GET requests, set JsonRequestBehavior to AllowGet.
and indicating my "actionUrl" in the SCRIPT_NAME server variable. The REQUEST_METHOD is GET and QUERY_STRING is empty. There is also a HTTP_REFERER server variable which indicates it is coming from the page with the above $.ajax() call, so it doesn't seem likely it's someone is accessing the JSON action manually.
The only thing I have come up with is that something strange might happen if the user hits the Back or Refresh buttons in the browser, but that doesn't seem right.
Is there any solid explanation of how that one GET request could have been generated?
I can only guess what probably happened. If someone is looking at the Network tab of the Developer Tools in their browser, they can see the file being called. If they right click the file and "Open in new tab", the page will be opened with a GET, and you will see the error message. Someone was probably testing and manually opened the link.
Probably $.ajax uses some get requests by default, use $.post() instead of it.
$.post( url, function( data ) {
$( ".result" ).html( data );
});

Categories