What happens when no response is received for a request? I'm seeing retries
Checkout this blog post that explains what is happening: http://geek.starbean.net/?p=393
According to HTTP/1.1 RFC 8.2.4:
If an HTTP/1.1 client sends a request which includes a request body, but which does not include an Expect request-header field with the “100-continue” expectation, and if the client is not directly connected to an HTTP/1.1 origin server, and if the client sees the connection close before receiving any status from the server, the client SHOULD retry the request.
Make sure you design your web app to tolerate these extra requests. And if you want the ajax request to do something only once, such as writing something to a database, then you need to design the request as idempotent. See: What is an idempotent operation?
Also, this highlights the differences between GET and POST operations: http://www.cs.tut.fi/~jkorpela/forms/methods.html
As a general design practice:
-GET operations should be designed as idempotent
-POST operations should be used for writing to databases, etc.
Related videos on Youtube
user1768233
Updated on October 22, 2020Comments
-
user1768233 over 3 years
The question I have is probably more of a browser related question I think, but its a pretty fundamental one I'd like to find the answer too as I venture into building a web application.
In my client side code I am doing an
$.ajax
call. This Post can take a while to respond. What I'm seeing is after a certain amount of time the request is being send again.I thought it was my
$.ajax
call sending it again, but no matter how many times I see the POST request on the server, I only see thebeforeSend
callback called once. I am fairly sure my code isn't sending it more than once, so I think its the browser retrying?I know my server is getting the request more then once as I ran up Wireshark and can see the post request multiple times. So my assumption is this is something to do with HTTP? I.e., if a response isn't received within a certain amount of time then the request is resent?
Here is a sample of my call below.
$.ajax({ async: false, type: 'POST', url: '<%= url_for('importDevice') %>', data: { device: val }, retryLimit: 0, //callback success: function(data) { alert('calling import'); if ( data == 'nomaster') { // Display a warning toast, with a title toastr.warning('You must set the Master Key first!', 'Warning'); $.ismasterset = false; //reset the form contents after added } else { $("div#content").html(data); } }, beforeSend: function(){ alert('in before send'); } });
This is all of the relevent code, 'retryLimit' isn't being used, I just haven't removed it from my code and yes the problem was there before I put it in.
EDITED with output from client and server.
ok I installed 'Live Http headers for Firefox'.
In the 'Generator' tab I see the one single call
'#request# POST http://testhost/importdevice'
I don't see the
POST
in the 'headers' section though, maybe thats because there's no response?In my webserver though I see 2 calls about 22 seconds apart.
[Sun Jan 13 03:08:45 2013] [debug] POST /importdevice (Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:17.0) Gecko/20100101 Firefox/17.0). [Sun Jan 13 03:09:07 2013] [debug] POST /importdevice (Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:17.0) Gecko/20100101 Firefox/17.0).
I can also see these same calls in wireshark...
This is why I was asking if this is normal behaviour to try to resend the request if a response doesn't come back, in a similar fashion to a TCP handshake and the
SYN
retransmission.NEW UPDATE
It doesn't seem to have anything to do with my Ajax call. If I create a button with a simple HREF.
i.e
<a href="/importdevice?device=serverA" class="btn btn-success">TestDirect</a>
Then in my 'Live HTTP headers output I get... just one instance.
#request# GET http://172.16.118.15/importdevice?device=serverA
But once again in my server logs I get.
[Sun Jan 13 03:20:25 2013] [debug] GET /importdevice (Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:17.0) Gecko/20100101 Firefox/17.0). [Sun Jan 13 03:20:48 2013] [debug] GET /importdevice (Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:17.0) Gecko/20100101 Firefox/17.0).
And in wireshark on the server I'm seeing it twice as well... and as expected my server code is called twice too... This is REALLY confusing to me.
-
T.J. Crowder over 11 yearsThat's obviously not your real call, as it contains syntax errors. Please use copy-and-paste.
-
Alexander over 11 yearsWhat's the
retryLimit
property doing there? Is this all the relevant code? -
user1768233 over 11 yearsok I've cut and pasted my code exactly. this doesn't through any errors, the URL is expanded out by my web frame work. but I've tested it with the direct url and I have the same issue.
-
user1768233 over 11 yearssorry 'retryLimit' isn't relavent.
-
-
user1768233 over 11 yearsThanks Paolo, Yeah I want async off. My browser is chrome, I've also tried safari and see the same behaviour. In chrome under development tools I see the one POST with the status 'PENDING'. However in my server logs and in wireshark I see the POST request come through twice. Thanks I'll install the Live httpHeaders plugin and see if that helps
-
user1768233 over 11 yearsUpdate above. It seems its nothing to do with Ajax...now I'm really lost.
-
user1768233 over 11 yearsthank you! that was exactly what I was looking for..plus more!
-
Yadu almost 11 yearsSo as per HTTP specifications, even non idempotent requests i.e. POST can be retried by the client
-
BigMacAttack almost 11 years@Yadu Yes, even POST requests can be retried by the client (as experienced by the question asker). But it's not accurate to call all POST requests non-idempotent. There are occasions where one might want to design a POST request as idempotent. Be sure to read the very last section at the bottom of this page; the section entitled "Possible reasons to use "POST" for idempotent queries".
-
BoB3K about 8 yearsSo, this is marked as answered, which I guess it is, but no one actually says if I can do anything about it other than do a lot of work on my server side to handle duplicate requests. Is there no way to tell browsers NOT to resend POST requests or disable their timeouts--preferably from javascript/ajax?
-
Kaman Wu about 7 yearsI have the similar problem now. Say the 1st request comes to server, the server need 3 minutes to process. After 2 minutes, the 2nd request comes in. My server will return 400 immediately. After another 1 minute, the server will return 200 (the 1st request finished). Is that correct? For now the problem is the client shows error when getting the 400 response. it will not wait for the 200 response.