Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
428 views
in Technique[技术] by (71.8m points)

jquery - What happens when no response is received for a request? I'm seeing retries

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 the beforeSend 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...