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

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

我正在testing这种情况下使用一个简单的node.js服务器3路由和铬浏览器。

/ : 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

在开发者控制台,使用jquery将ajax POST请求发送到/ hi

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

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

3

发出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)发出请求才会产生响应,它不会被重试。 只有一个随后的/睡眠请求会发生重试。

在浏览器中,networking选项卡显示类似的模式

 /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) 

尽pipe我们需要devise我们的web应用程序来容忍这些额外的请求(无论是浏览器还是其他中介),但这种不一致的浏览器重试看起来很奇怪。 我曾在Chrome(v16&v24)&firefox中观察过这种行为。

有人可以帮助我了解浏览器重试逻辑超时非幂等的请求?

其他相关的计算器问题

当没有收到任何请求的回应时会发生什么? 我看到了重试

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