Related but not duplicate: Chrome cancels URL_REQUEST after exactly 3 seconds
=> this question has been wrongly marked as Resolved. Here, I try to bring new elements to understand what is going on.
TLDR and questions:
Chromium-based browsers are canceling requests taking more than 3 seconds if the URL was written without http(s)://
then making another request, resulting in 2 hits server-side. (see detailed logs below)
-
a) Is there a way to modify this behavior?
In other words, a way to tell Chromium browsers to “wait more” instead of canceling the request and doing another one. -
b) How do you handle it? Or maybe a way to avoid it, other than improving performances of the URL, of course 🙂
Findings and summary:
- this issue seems to occur only in Chromium-based browsers (Google Chrome, Microsoft Edge, …)
- this issue seems to occur only if you try to access any URL without specifying the scheme
http://
orhttps
. - this issue occurs whether the domain has a
http->https
redirect or not. (see detailed logs below) - this issue has nothing to do with HSTS. I’ve tested it: with HSTS enabled, Chrome just replaces the 301/302
http->https
redirect to a307 internal redirect
request instead) - this issue appears both with HTTP/1 and HTTP2 (tested in 2 different servers)
- this issue appears only when the initial request is taking at least 3 seconds.
Detailed logs:
- Without HTTP => HTTPS redirection in the global vhost configuration
# Apache logs
[24/May/2024:15:35:54] 1.2.3.4 - www.example.com:443 "GET /testing HTTP/1.1" 200 "www.example.com/testing" bytes:34 time:4042159
[24/May/2024:15:35:57] 1.2.3.4 - www.example.com:80 "GET /testing HTTP/1.1" 200 "www.example.com/testing" bytes:34 time:4027890
[24/May/2024:15:36:01] 1.2.3.4 - www.example.com:80 "GET /favicon.ico HTTP/1.1" 200 "www.example.com/favicon.ico" bytes:0 time:326
# PHP logs
[2024-05-24 15:35:54.478306] 1.2.3.4 local.INFO: [REQUESTED_AT_15:35:54.477500] [https://www.example.com/testing] Request received, now I will wait 4 s
[2024-05-24 15:35:57.290657] 1.2.3.4 local.INFO: [REQUESTED_AT_15:35:57.290000] [http://www.example.com/testing] Request received, now I will wait 4 s
[2024-05-24 15:35:58.478763] 1.2.3.4 local.INFO: [REQUESTED_AT_15:35:54.477500] [https://www.example.com/testing] Done, I waited 4 s! It is now 15:35:58.478700
[2024-05-24 15:36:01.291083] 1.2.3.4 local.INFO: [REQUESTED_AT_15:35:57.290000] [http://www.example.com/testing] Done, I waited 4 s! It is now 15:36:01.291000
As you can see, the request sent at 15:35:54 is not yet complete, but Chrome is sending another one, resulting in 2 requests server side (that can create issues, duplicates, etc).
- With HTTP => HTTPS enabled in the global vhost configuration
# Apache logs
[24/May/2024:15:53:25] 1.2.3.4 - www.example.com:443 "GET /testing HTTP/1.1" 200 "www.example.com/testing" bytes:34 time:4244717
[24/May/2024:15:53:28] 1.2.3.4 - www.example.com:443 "GET /testing HTTP/1.1" 200 "www.example.com/testing" bytes:34 time:4040528
[24/May/2024:15:53:32] 1.2.3.4 - www.example.com:443 "GET /favicon.ico HTTP/1.1" 200 "www.example.com/favicon.ico" bytes:0 time:364
# PHP logs
[2024-05-24 15:53:25.953574] 1.2.3.4 local.INFO: [REQUESTED_AT_15:53:25.948300] [https://www.example.com/testing] Request received, now I will wait 4 s
[2024-05-24 15:53:28.739584] 1.2.3.4 local.INFO: [REQUESTED_AT_15:53:28.738700] [https://www.example.com/testing] Request received, now I will wait 4 s
[2024-05-24 15:53:29.954046] 1.2.3.4 local.INFO: [REQUESTED_AT_15:53:25.948300] [https://www.example.com/testing] Done, I waited 4 s! It is now 15:53:29.954000
[2024-05-24 15:53:32.740055] 1.2.3.4 local.INFO: [REQUESTED_AT_15:53:28.738700] [https://www.example.com/testing] Done, I waited 4 s! It is now 15:53:32.739900
Here is a MRE:
- Open a Chromium-based browser
- Open dev tool on Network tab
- paste your “slow” URL, without
http://
norhttps://
(ex:www.example.net/
) - press Enter, and confirm the behavior:
- first request sent
- then after 3s, the browser cancels it, and requests another one
(It’s Laravel code but it’s the same with regular vanilla PHP of course)
<?php
Route::get('/testing', function () {
$u = url()->full();
$s = 4;
$now = DateTime::createFromFormat('U.u', microtime(true));
$t = $now->format("H:i:s.u");
Log::info("[REQUESTED_AT_$t] [$u] Request received, now I will wait $s s");
sleep($s);
$now = DateTime::createFromFormat('U.u', microtime(true));
$t2 = $now->format("H:i:s.u");
Log::info("[REQUESTED_AT_$t] [$u] Done, I waited $s s! It is now $t2");
echo "Page loaded, OK";
});
As described here, you might reproduce this issue without an actual “slow” URL, just by throttling your connection speed.