Ответ 1
TL; DR: Chrome интерпретирует этот заголовок ответа как keep-alive
и поддерживает постоянное соединение, в то время как Firefox закрывает каждое соединение.
Я наткнулся на этот вопрос, пытаясь оптимизировать время загрузки страницы для моего сайта.
В ссылочном RFC я не нашел ничего о том, как можно обрабатывать несколько записей в заголовке Connection
. Мне показалось, что реализация может выбирать из двух возможных вариантов:
- Если есть несколько записей, вы можете выбрать, который лучше всего подходит вашим потребностям.
- Если внутри есть
close
, вы можете закрыть соединение после передачи
Итак, мне нужно было выяснить. Давайте сделаем еще более глубокое исследование:
Я заметил, что Chrome всегда отправлял HTTP/1.1 запрос с Connection: keep-alive
, и моя конфигурация по умолчанию Apache всегда отвечала заголовком Connection: close
. Поэтому я начал исследовать и посмотрел на сегменты TCP с Wireshark.
Chrome должен отображать 14 элементов для отображения веб-сайта, в основном из них - статические вещи, такие как изображения или файлы css. И потребовалось 14 соединений TCP, и это заняло много времени (примерно 1,2 секунды). После каждого запроса на изображение (например,) появился сегмент TCP с флагом FIN
, установленным в 1.
А как насчет Chrome против Firefox? Кажется, что у Chrome есть максимальное количество одновременных подключений к одному серверу из 6. Firefox имеет более гранулированную конфигурацию и отличается постоянством (максимум 6, видимый примерно: config) и непостоянный (максимальные числа сильно различались в разных источниках). Но подождите... Оба, Chrome и Firefox отправляют заголовки запросов HTTP/1.1 с помощью Connection: keep-alive
, поэтому оба должны быть ограничены 6 (так как это запрос для открытия постоянного соединения).
Я решил попробовать простой трюк и добавил следующие строки в мой .htaccess
в корневой папке:
<ifModule mod_headers.c>
Header set Connection keep-alive
</ifModule>
Теперь сервер отвечает:
Connection: keep-alive, close
Теперь я снова посмотрел на сегменты TCP: теперь на моем сервере было только 9 соединений с Chrome, и только 3 с флагом FIN
, установленным в 1. Таким образом, этот трюк, похоже, работал. Но почему были эти 3 соединения, которые закрыли соединение после передачи данных? Это были запросы PHP, как подтвержден HTTP-заголовок X-Powered-By: PHP/5.4.11
.
А как насчет Firefox? Были еще те 14 запросов!
Как это исправить и заставить процессы fcgi работать с keep-alive тоже?
Я добавил следующие строки в мой раздел virtualhost конфигурации httpd.conf:
KeepAlive On
KeepAliveTimeout 5
MaxKeepAliveRequests 100
и удалили те, которые были добавлены в .htaccess
. Теперь сервер не отправляет путаницу - Connection: keep-alive, close
, но только Connection: keep-alive
, и все работает отлично!
Вывод:
Заголовок с полем подключения, установленным на
HTTP/1.1 200 OK
Connection: keep-alive, close
будет интерпретироваться Chrome как keep-alive
, в то время как Firefox, похоже, закрывает каждое соединение. Кажется, что это зависит от фактической реализации.
Итак, если вы хотите внедрить клиент для обработки заголовков ответов, содержащих Connection: keep-alive, close
, я бы предложил попробовать использовать keep-alive, если вам нужно больше одного запроса. Самое худшее, что может случиться: сервер закроет соединение, и вам нужно будет снова подключиться (это точно другой вариант, который у вас был бы!)