Перевод статьи «The power of http headers and 4 examples you did not know before».
Существует достаточно много http-заголовков. Большинство из них достаточно просты. Но есть также довольно мощные и при этом не слишком известные http-заголовки.
Hello http (заголовки)
Практически все в вебе пересылается через http. Эта аббревиатура знакома даже не-разработчикам, потому что они постоянно видят ее как часть ссылок.
Http расшифровывается как Hypertext Transfer Protocol. Этот протокол дает нам возможность пересылать гипертекст между браузером и сервером. Это отличная технология, работающая практически со времен изобретения веба, постоянно развивающаяся и предлагающая все больше крутых функций.
Что такое http-заголовки?
Если вы разработчик, то скорее всего вы уже слышали об http-заголовках, по крайней мере в контексте CORS. Но что из себя представляют эти заголовки и как их использовать?
Давайте сначала разберем, что они делают и как ими пользоваться.
Когда браузер запрашивает ресурс, например, страницу этого блога, он обращается к серверу с запросом. Этот запрос выглядит примерно так:
fetch("https://www.lorenzweiss.de/race_conditions_explained/", { credentials: "include", headers: { accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3", "accept-language": "en,en-US;q=0.9,de-DE;q=0.8,de;q=0.7", "cache-control": "max-age=0", "sec-fetch-mode": "navigate", "sec-fetch-site": "same-origin", "sec-fetch-user": "?1", "upgrade-insecure-requests": "1", }, referrerPolicy: "no-referrer-when-downgrade", body: null, method: "GET", mode: "cors", });
Вы видите URL или местонахождение ресурса, некоторые сведения о запросе, а также множество заголовков, касающихся запроса. Таким образом ваш браузер сообщает серверу определенные сведения о запросе. Например, какого типа данные он принимает или как клиент обрабатывает кеш.
Сервер отвечает на посланный ему запрос, и в своем ответе тоже пересылает кое-какие заголовки. Выглядеть это может так:
:authority: www.lorenzweiss.de :method: GET :path: /race_conditions_explained/ :scheme: https accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 accept-encoding: gzip, deflate, br accept-language: en,en-US;q=0.9,de-DE;q=0.8,de;q=0.7 cache-control: max-age=0 cookie: _ga=GA1.2.1173972759.1584812492; _gid=GA1.2.2076192721.1594044231 sec-fetch-mode: navigate sec-fetch-site: same-origin sec-fetch-user: ?1 upgrade-insecure-requests: 1 user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36
Здесь содержится некоторая информация об использовании ресурса, которую сервер хотел бы сообщить браузеру. Например, если там используются cookies, то в заголовках указывается, какая кодировка применялась.
Вы можете представить это как листочек, который прикрепляется поверх посылки из онлайн-магазина. В таком листочке вы получаете сведения о контексте и ресурсе, который вы заказывали.
Большинство заголовков имеют довольно хорошие значения по умолчанию, которые можно не менять. При этом некоторые заголовки (например CORS-заголовки) могут представлять особую важность. Но есть еще много заголовков, о которых вы могли никогда не слышать, а между тем они очень полезны и стоит научиться ими пользоваться.
Заголовки, которых вы не знаете
Не волнуйтесь, в этой статье мы не будем касаться CORS. Мы рассмотрим http-заголовки, которые используются довольно редко, но могут помочь существенно улучшить коммуникацию между сервером и браузером.
If-Range
Что это такое и зачем это нужно?
Представьте, что вы начинаете скачивать объемный ресурс, например видео, изображение и т. п., а загрузка прерывается из-за проблем со связью. При помощи If-Range вы можете сообщить серверу, что представление не изменилось и можно переслать запрошенные в Range части. Таким образом будет пересылаться не весь ресурс (заново), а только недостающие части.
Это может быть очень полезно, когда вы работаете с большими ресурсами, а также когда предполагаются проблемы со связью (характерно для мобильных устройств). Благодаря этому заголовку получится загрузить весь ресурс, даже если соединение будет прерываться.
Как пользоваться
Можно использовать или с датой последней модификации ресурса, или с Etag, что может помочь при повреждении ресурса.
If-Range: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT If-Range: <etag>
Пример
If-Range: Wed, 21 Oct 2015 07:28:00 GMT
Vary
Vary появился в те времена, когда http использовался не только для веб-страниц.
В его основе лежит идея использования http для обмена информацией во многих (разных) форматах. Каким образом? Этот заголовок сообщает серверу, в каком виде нужно предоставить информацию.
В наше время это может быть очень полезно, если у вас есть разные ресурсы для разных пользователей. Например, для пользователей десктопов и мобильных устройств. Представьте, что на сервере для одного ресурса хранятся три разных изображения — для разных устройств. Вы можете использовать заголовок Vary, чтобы сообщить серверу о необходимости определить устройство пользователя и на основе этого решить, изображение какого размера нужно выслать.
Пример
Возьмем тот же пример с изображениями, зависящими от устройства. Чтобы сообщить серверу, что он должен получить информацию об устройстве пользователя, вы можете просто передать в заголовке «user agent».
Vary: User-Agent
Как пользоваться
Просто вставьте заголовок, который сервер должен проверить, прежде чем решить, какой ресурс отсылать.
Vary: <header>
Content-Disposition
Когда серверу отправляется запрос для отображения сайта, браузеру понятно, что он должен отобразить ресурс, который придет в ответе. Но может быть и такое, что сервер отсылает ресурс, который браузер должен автоматически начать загружать на компьютер пользователя (это может быть картинка или pdf и т. п.). При помощи заголовка Content Disposition сервер может сообщить браузеру, что именно тот должен делать с прилагаемым ресурсом.
Пример
Content-Disposition: attachment; filename="data.pdf"
Если определить значение Content-disposition как attachment, браузер будет знать, что этот ресурс предназначен для скачивания, а не просто для показа.
Как пользоваться
Вы можете определить этот заголовок как inline или attachment, причем inline это значение по умолчанию.
Content-Disposition: <inline | attachment>
Feature-Policy
Это довольно новый заголовок, поэтому он поддерживается пока только современными браузерами. Но я все равно хочу его упомянуть, потому что считаю очень полезным в некоторых случаях. В общем, Feature-Policy сообщает браузеру, какие функции или API браузер должен предоставить документу и его фреймам для использования.
Например, он может запретить все скрипты или фреймы на сайте, чтобы разрешить чувствительные API, такие как камера или микрофон.
Как пользоваться
Feature-Policy: <directive> <allowlist>
Directive — это название функционала. Полный список вариантов можно посмотреть здесь. А allowlist определяет, какие именно источники могут использовать то, что указано в directive.
Пример
Предположим, что мы хотим, чтобы наш сайт не мог использовать ни микрофон, ни камеру. Благодаря этому заголовку документ или содержащийся в нем фрейм не получат доступа к этим функциям.
Feature-Policy: microphone 'none'; camera 'none'
Другие заголовки
Есть и другие заголовки, стоящие упоминания:
Заключение
Https-заголовки — отличная и очень полезная вещь. Порой они могут быть довольно сложными, а кроме того разработчику тяжело охватить все доступные заголовки и изучить, какие именно преимущества они дают. К тому же, когда вы создаете сайт, особенно в части фронтенда, вы не слишком часто имеете с ними дело, за исключением разве что CORS-заголовков. Но я думаю, что из-за этого разработчики упускают некоторые возможности. Http-заголовки обеспечивают куда лучшую коммуникацию между сервером и пользователями, а все мы знаем, что коммуникация — ключ к хорошим отношениям.
Надеюсь, в этой статье мне удалось познакомить вас с миром http-заголовков. Если здесь пропущен еще какой-то особенно интересный и полезный заголовок — не стесняйтесь добавлять в комментариях!
[customscript]techrocks_custom_after_post_html[/customscript]
[customscript]techrocks_custom_script[/customscript]