超时POST请求的浏览器重试行为不一致



我偶尔会遇到POST请求重试,由于超时,服务器没有响应。所有现代浏览器都有对幂等请求(GET, HEAD等)的重试逻辑,但我无法解释为什么POST请求会发生这种情况。

我正在用一个简单的node.js服务器和3个路由和chrome浏览器测试这个案例。

/       : gives a html page with jquery and code snippets to fire ajax requests
/hi     : gives a text response 'hello'
/sleep  : request will timeout without any response 

默认情况下,node.js http服务器会在2分钟后超时。

retry.js

var http = require('http');
var server = http.createServer();
server.on('request', function(req, res) {
    console.log(new Date() + ' ' + req.method + ' request on ' + req.url);
    if (req.url === '/sleep') {
        console.log('!!! sleeping');
    } else if (req.url === '/') {
        html = "$.post('/hi', {'for':'server'}, function() { console.log(arguments) } ).error(function() { console.log(arguments) })";
        html += "<br><br>";
        html += "$.post('/sleep', {'for':'infinite'}, function() { console.log(arguments) } ).error(function() { console.log(arguments) })";
        html += '<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>';
    
        res.writeHead(200, {'Content-Type': 'text/html'});
        res.end(html);
    } else {
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('hello');
    }
});
server.listen(2020);
console.log('server listening on port 2020');

运行它
$ node retry.js 
server listening on port 2020

1

Load this page in browser http://localhost:2020
Fri Mar 01 2013 12:21:59 GMT+0530 (IST) GET request on /
Fri Mar 01 2013 12:21:59 GMT+0530 (IST) GET request on /favicon.ico
2

在Dev控制台中,使用jquery向/hi发送ajax POST请求

$.post('/hi', {'for':'server'}, function() { console.log(arguments) } ).error(function() { console.log(arguments) })

星期五Mar 01 2013 12:22:05 GMT+0530 (IST) POST request on/hi

3

向/sleep发送POST请求,结果2分钟后重试,4分钟后错误退出。

$.post('/sleep', {'for':'infinite'}, function() { console.log(arguments) } ).error(function() { console.log(arguments) })

服务器日志显示2个请求

Fri Mar 01 2013 12:22:21 GMT+0530 (IST) POST request on /sleep
!!! sleeping
Fri Mar 01 2013 12:24:21 GMT+0530 (IST) POST request on /sleep
!!! sleeping

再次启动,2分钟内错误退出,无需重试。

Fri Mar 01 2013 12:30:01 GMT+0530 (IST) POST request on /sleep
!!! sleeping ?

它不会被重试,直到我们触发一个请求/hi(或任何其他url)的结果响应。并且重试只发生在一个后续请求/sleep。

在浏览器中,network选项卡显示了类似

的模式
/hi - success 
/sleep - cancelled - 4 mins (retry happens)
/sleep - cancelled - 2 mins (no retry)
/sleep - cancelled - 2 mins (no retry)
/hi - success 
/sleep - cancelled - 4 mins (retry happens)
/sleep - cancelled - 2 mins (no retry)
/sleep - cancelled - 2 mins (no retry)

虽然我们需要设计我们的web应用程序来容忍这些额外的请求(无论是来自浏览器还是任何其他中介),但这种不一致的浏览器重试看起来很奇怪。我在chrome (v16 &v24),firefox。

有人能帮我理解浏览器重试逻辑背后超时的非幂等请求吗?

其他相关的stackoverflow问题

如果没有收到请求的响应会发生什么?I'm看到重试

浏览器在收到服务器的响应之前,会在连接关闭时重试请求(包括post)。这在HTTP 1.1规范第8.2.4节中定义。

最新更新