jQuery ajax remains pending / stalled - javascript

I've read a bunch of other SO threads but none of them had an answer that worked for me.
I have a simple jQuery script that sends some data over ajax to a Node.js server. Basically this:
$.ajax
url: '/v2/send/[id]'
method: 'POST'
data: 'test'
success: ->
console.log 'Complete', arguments
When I run this code, in the network tab in Chrome the request appears but it's "stalled". It stays that way for minutes, I have read posts from other people where it eventually did send but so far I haven't noticed that happening.
I'm developing the server as well, and I'm logging every request to the application, so I can see that in fact nothing comes in.
I currently have nothing else in my script (this is the whole thing).
So far I've checked and verified:
That jQuery is loaded ($ is set)
That the 'submit' event is in fact triggered (by adding an alert which popped up)
That the request is being created (AjaxStart and AjaxSend happen)
That the URL is correct (right-clicking the request in the network tab -> 'open in new tab' shows me the data I wanted)
That there are no other requests / connections getting in the way (I only have 5 other items in the network tab)
That my server actually logs all requests (I hit it with a bunch of random requests using Postman and they all showed)
Am I missing something obvious here, or is jQuery or Chrome at fault? How can I fix this to actually send the request?

Related

Api PUT request showing as "cancelled" with error message "TypeError: failed to fetch"

This is a weird situation, I've looked at loads of SO questions and nothing is quite like it. Hopefully I can get some feedback regarding it
I'm creating a new web page in an existing application and am trying to execute a simple PUT api call and for some reason it is showing a status of cancelled on my network tab in chrome dev tools. The server I'm hitting is a VM on my local machine. I can hit the same endpoint from a different existing page in my application and it goes through just fine so I know that there's nothing wrong with the endpoint. Here's some screenshots:
This is what the network tab in chrome dev tools looks like:
This is what I see when I click on the "cancelled" put call:
and this is what shows on the console tab of chrome dev tools:
One thing to note is that in the second screenshot under the General section on the right it doesn't have anything listed for Request Method, Status Code or Remote Address, see this screenshot of the successful api put request I referred to earlier for reference:
The really weird thing is that my database is getting updated with the updated data, so in some way even though the PUT is showing as cancelled it's working to some degree.
The call originates from a vue component on my page and my backend is in PHP if that matters at all.
here is the call in my .js file that executes the PUT:
return await SimpleService.put(`${app.API_URL}/matching/questions/${borrowerId}`,
JSON.stringify(answerData), {contentType: 'application/json'})
So, I recognize that without seeing all the code attached to this it isn't really realistic to ask for a black and white answer but if someone can even just give me some ideas of things to check I would greatly appreciate it.
I've tried to include everything I can think of without including unnecessary things but if any additional information is needed from me to figure this out please let me know.
Phil was right in his comment, here's an explanation from what I understand. When the button was clicked that submitted the api call the default behavior for the button click was executed, which was to re-load the page. Well, when a page is reloaded any in flight network requests are not being tracked anymore, which is why the request was showing as "cancelled" in my console tab. And that also explains why the api call was successful in updating the database, because there wasn't any problem with the actual request. Here's the steps I took to fix my problem:
remove the onClick event from my button that was calling my javascript function that begins the api call process
add this code to the form tag my button lives inside: #submit.prevent="myJavascriptFunctionThatStartsAPICall()"
Adding the .prevent prevents the default behavior of the page reloading from happening thus when the response is returned back to the page the page is still listening for it. Problem solved.
I hope this helps someone else out.
Its just the request status. In backend you should return status code 200 if everything is correct. Chrome thinks that the request got fail because you return a error code like 499 Client Closed Request or 444 No Response.

jQuery $.get() is blocking other requests

I'm developing a web application and use jQuery to make asynchronous HTTP requests to my API. I have a detail view where you can see a lot of information of a specific object stored in the database. Because there is a lot of information and data that is linked to other objects, I make different calls to my API to gather different information for my views.
In the 'detail view' I have some kind of widgets that show the requested information. For that, I make about 5-7 HTTP GET requests to my API. When using the debugger (both Safari and Firefox), I can see that some requests are blocking other requests and the page takes a lot of time until everything is loaded and shown to the user.
I make a request like this:
$.get("api/api.php?object=myobject&endpoint=someendpoint", function(data) {
// data is JSON formatted
$("#my-widget input").val(data["name"]);
});
And another one e.g. like this:
$.get("api/api.php?object=anotherobject&endpoint=anotherendpoint", function(data) {
// data is JSON formatted
$("#other-widget input").val(data["somekey"]);
});
If the first request takes a little longer to finish, it blocks the second request until the callback function of the first request finished. But why? I thought that those calls are asynchronous and non-blocking.
I want to build a fast web application for a company where the requests are only made inside the local network, so a request should only take about 10-50ms (or even less). But the page takes about 10 seconds to show up with all information.
Am I doing something wrong? Or is there a JavaScript framework that can be used for exactly this problem? Any help is appreciated!
EDIT: As you can see in the screenshot, the requests have to wait some seconds, and if the request is fired, it takes a few seconds until a response comes back.
If I call the URL directly in my browser or do a GET request using curl it is a lot faster.
EDIT2: Thanks #CBroe! The session file write lock was the problem. As long as the session file is locked, no other script can run until the previous script finished. I just called session_write_close() immediately after session_start() and it runs a lot faster now.
Attention: Use session_write_close() only if you don't need to write to the $_SESSION array. Reading is possible after that, but writing not. (See this topic for further details: https://stackoverflow.com/a/50368260/1427878)

HTML form seems to be submitting *both* POST and GET?

This is not a duplicate of questions such as this, but rather the opposite: I have a form that I'm submitting via jQuery
$('<form>', {
action : 'service',
method : 'post',
target : '_blank'
}).append(
$('<input>', {
type : 'hidden',
name : 'payload',
value : JSON.stringify(payload)
})
).appendTo('body').submit().remove();
This is done so that I can open a different page with HTML.
Since I need to submit quite a lot of complex information, what I actually do is serialize them all into a big JSON string, then create a form with only one field ("payload") and submit that.
The receiving end has a filter that goes like this:
if the method is POST,
and there is only one submitted variable,
and the name of that one variable is "payload",
then JSON-decode its value and use it to create fake GET data.
So when the GET data grows too much I can switch methods without modifying the actual script, which notices no changes at all.
It always worked until today.
What should happen
The server should receive a single POST submission, and open the appropriate response in a popup window.
What actually happens instead
The server does receive the correct POST submission...
...apparently ignores it...
...and immediately after that, the browser issues a GET with no parameters, and it is the result of that parameterless GET that gets (pardon the pun) displayed in the popup window.
Quite unsurprisingly, this is always a "You did not submit any parameters" error. Duh.
What I already did
verified that this method works, and has always worked for the last couple of years with different forms and different service endpoints
tried replacing the form with a hardcoded <FORM> in HTML, without any jQuery whatsoever. Same results. So, this is not a jQuery problem.
tried with different browsers (it would not have helped if it only worked on some browsers: I need to support most modern browsers. However, I checked. Luckily, this failure reproduces in all of them, even on iPhones).
tried sending few data (just "{ test: 0 }").
tried halting the endpoint script as soon as it receives anything.
checked Stack Overflow. I found what seems to be the same problem, in various flavours, but it's of little comfort. This one has an interesting gotcha but no, it does not help.
checked firewalls, proxies, adblockers and plugins (I'm now using plain vanilla Firefox).
called the IT guys and asked pointed questions about recent SVN commits. There were none.
What I did not yet do
Check the HTTPS conversation at low level (I don't have sufficient access).
Compared the configuration, step by step, of a server where this works and the new server where it does not.
Quite clearly, put my thinking hat on. There must be something obvious that I'm missing and I'm setting myself up for a sizeable facepalm.
Use a tool like hurl.it or Postman to manually send a request to the server. The tools will nicely display the response from the server including all HTTP headers. I suspect the server responds with a redirect (Status code 30X) which leads to a GET request being issued after the POST completes.
Update: HTTP redirects
HTTP redirects do not necessarily use the same HTTP method or even the same data to issue a request to the redirect target. Especially for non-idempotent requests this could be a security issue (you don't generally want your form submission to be automatically re-submitted to another address). However, HTTP gives you both options:
[...] For this reason, HTTP/1.1 (RFC 2616) added the new status codes 303 and 307 [...], with 303 mandating the change of request type to GET, and 307 preserving the request type as originally sent. Despite the greater clarity provided by this disambiguation, the 302 code is still employed in web frameworks to preserve compatibility with browsers that do not implement the HTTP/1.1 specification.
[from Wikipedia: HTTP 302]
Also for 301s:
If the 301 status code is received in response to a request of any type other than GET or HEAD, the client must ask the user before redirecting.
[from Wikipedia: HTTP 301]

Pending request in AngularJS application

I noticed that when I was "away from keyboard" over 5-10min and I make a call to backend (GET, POST or something) the first call is directly the request in question and the browser not send before the OPTIONS request so the call remains pending and if I make a second call works fine, because send first the OPTIONS (the browser understands that it doesn't send OPTIONS call before) and after successfull response start the GET...
I think the browser cache the "Authorization of request" and that's is why the first call after some minutes goes in pending: browser doesn't send OPTIONS call before...
I use Chrome and I never tested with Firefox or something else...
It's a big problem because if a user is afk for some reason, he need to press button twice for what he need to do.
Anyone know fix/trick to avoid this? I'm working on angularjs applications, and the http request are made with $http.

Forcing an HTTP request to fail in browser

Is it possible to make an http request that has been sent to a server by the browser fail without having to alter the javascript?
I have a POST request that my website is sending to the server and we are trying to test how our code reacts when the request fails (e.g. an HTTP 500 response). Unfortunately, the environment that I need to test it in has uglified and compressed javascript, so inserting a breakpoint or altering the javascript isn't an option. Is there a way for us to utilize any browser to simulate a failed request?
The request takes a long time to complete, so using the browser's console to run a javascript command is a possibility.
I have tried using window.stop(), however, this does not work since I need to failure code to execute.
I am aware of the option of setting up a proxy server, but would like to avoid this is possible.
In Chrome (just checked v63), you can actually block a specific URL (or even a whole domain) from the Network tab. You only need to right-click on the entry and select Block request URL (or Block request domain.)
One possible solution is to modify the XMLHttpRequest objects that will be used by the browser. Running this code in a javascript console will cause all future AJAX calls on the page to be redirected to a different URL (which will probably give a 404 error):
XMLHttpRequest.prototype._old_open =
XMLHttpRequest.prototype._old_open || XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
return XMLHttpRequest.prototype._old_open.call(
this, method, 'TEST-'+url, async, user, pass);
};
Don't overlook the simplest solution: disconnect your computer from the Internet, and then trigger the AJAX call.
Chrome's dev tools have an option to "beautify" (i.e. re-indent) minified JavaScript (press the "{}" button at the bottom left). This can be combined with the "XHR breakpoint" option to break when the request is made. XHR breakpoints don't support modifying the response though AFAIK, but you should be able to find a way to do it via code.
To block a specific URL and make an API call failure, you just need to follow below steps:
Go to Network tab in your browser.
Find that API call which needs to fail(as per your requirement).
Right click on that API call and
Click on 'Block Request URL', you can unblock as well in same manner as the option will turn into 'Unblock'
Just type at the brower a changed URL, e.g. the well formed URL e.g. http://thedomain.com/welcome/ by another placing "XX": http://thedomain.com/welcomeXX/ , that will cause a 404 error (not found)

Categories

Resources