Для запроса документов с веб-серверов браузеры используют протокол HTTP. Возможно, вы знаете это имя из адресной строки (оно может быть скрыто сейчас, но когда вы щелкнете по адресной строке, скопируете URL-адрес и вставите его в какой-либо текстовый редактор, вы увидите http://
в начале). HTTP - это простой текстовый протокол. Это работает так:
Во-первых, ваш браузер подключается к серверу веб-сайта и отправляет URL-адрес документа, который он хочет загрузить (веб-страницы также являются документами), а также некоторые сведения о самом браузере (User-Agent и т.д.). Например, чтобы загрузить главную страницу на сайте SuperUser, http://superuser.com/
, мой браузер отправляет запрос, который выглядит следующим образом:
GET / HTTP/1.1
Host: superuser.com
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.0 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: [removed for security]
DNT: 1
If-Modified-Since: Tue, 09 Jul 2013 07:14:17 GMT
Первая строка указывает, какой документ должен вернуть сервер.
Другие строки называются заголовками; они выглядят так:
Header name: Header value
Эти строки отправляют дополнительную информацию, которая помогает серверу решить, что делать.
Если все хорошо, сервер ответит отправкой запрошенного документа.
Ответ начинается с сообщения о состоянии, за которым следуют несколько заголовков (с подробной информацией о документе) и, наконец, если все хорошо, содержимое документа. Вот как выглядит ответ сервера SuperUser на мой запрос:
HTTP/1.1 200 OK
Cache-Control: public, max-age=60
Content-Type: text/html; charset=utf-8
Expires: Tue, 09 Jul 2013 07:27:20 GMT
Last-Modified: Tue, 09 Jul 2013 07:26:20 GMT
Vary: *
X-Frame-Options: SAMEORIGIN
Date: Tue, 09 Jul 2013 07:26:19 GMT
Content-Length: 139672
<!DOCTYPE html>
<html>
[...snip...]
</html>
После последней строки сервер SuperUser закрывает соединение.
Первая строка (HTTP/1.1 200 OK
) содержит код ответа, в данном случае это 200 OK
. Это означает, что сервер решил, что может вернуть документ в соответствии с запросом, и обещает, что последующее содержимое будет таким документом. Если это не тот случай, код будет чем-то другим, и он предоставит некоторое указание причины, по которой сервер не просто возвращает документ в качестве ответа: например, если он не может найти запрошенный документ, он должен вернуть 404 Not Found
, и если вам не разрешен доступ к рассматриваемому контенту, он должен вернуть 403 Forbidden
.
После этой первой строки статуса следуют заголовки ответа; они предоставляют больше информации о возвращаемом контенте, например, о его Content-type
.
Следующая пустая строка. Это сигнализирует о том, что больше не будет заголовков ответа. Все, что за этой строкой, является содержанием запрошенного документа. Так что в приведенном выше примере, <!DOCTYPE html>
- это первая строка домашней страницы SuperUser (документ HTML). Если бы я запрашивал документ для загрузки, это, вероятно, были бы некоторые бессмысленные символы, потому что большинство форматов документов не читаются без предварительной обработки.
Вернуться к заголовкам. Самый интересный для нас - последний, Content-Length
. Он сообщает браузеру, сколько байтов данных следует ожидать после пустой строки, поэтому в основном это размер документа, выраженный в байтах. Этот заголовок не является обязательным и может быть опущен сервером. Иногда размер документа не может быть предсказан (например, когда документ создается на лету), иногда ленивые программисты не включают его (довольно часто на сайтах загрузки драйверов), иногда сайты создаются новичками, которые не знают такого заголовка.
В любом случае, какой бы ни была причина, заголовок может отсутствовать. В этом случае браузер не знает, сколько данных сервер собирается отправить, и поэтому отображает размер документа как неизвестный, ожидая, пока сервер закроет соединение. И это причина неизвестных размеров документов.