当前位置: 首页 > 面试题库 >

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

东方镜
2023-03-14
问题内容

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

我正在使用具有3条路由和chrome浏览器的简单node.js服务器测试这种情况。

/       : 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向/ hi发出ajax POST请求

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

2013年3月1日星期五12:22:05 GMT + 0530(IST)在/ 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(或其他任何网址)发出导致响应的请求之前,不会重试该请求。然后仅对/ sleep一个后续请求进行重试。

在浏览器中,“网络”标签显示的模式如下

/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中观察到了这种行为。

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


问题答案:

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



 类似资料:
  • 问题内容: 我正在写一个基于AJAX / COMET的在线聊天室。我的设计是: 请求 -----------------等待------------------------->发送转储数据 -----------------等待------------------------->发送转储数据 -----------------等待------------------------->发送转储数据 -

  • 问题内容: 浏览器是否内置了超时功能,如果可以,它们是什么? 我有一个页面,该页面在最多运行5分钟的进程上执行AJAX调用。有人说浏览器在2分钟后超时,但不知道这有什么道理。 问题答案: 它取决于浏览器。“默认情况下,InternetExplorer的KeepAliveTimeout值为一分钟,其他限制因素(ServerInfoTimeout)为两分钟。这两种设置都会导致InternetExplo

  • 来个大佬看一下,有没有好办法。ε=(´ο`*))) 我在IDEA里面用java请求 https://fapi.binance.com/fapi/v1/ticker/price?symbol=BTCUSDT 这个地址,无论我用httpsURLConnection,还是OkHttp,还是hutool,统统连接超时,浏览器可以访问这个地址,python也可以请求成功。就java不行。 查了查有说是要加这

  • 我正在尝试为NBA数据创建一个网络刮板。当我运行以下代码时: 请求因错误而超时: 文件“C:\ProgramData\Anaconda3\lib\site packages\requests\api.py”,第70行,在get返回请求中('get',url,params=params,**kwargs) 文件“C:\ProgramData\Anaconda3\lib\site packages\r

  • 我有一个Spring Boot应用程序,我想实现的是,当我的Rest控制器需要更长的时间来处理请求时,只需发送错误而不继续处理请求。这可能吗?我如何以某种方式实现它,而无需在控制器级别进行修改,而是在应用程序级别进行修改。这是在最新的Spring启动