Войти через VK Войти через FB Войти через Google Войти через Яндекс
Поиск по сайту
HTTP-заголовки
Заголовки, отправленные вашим браузером
При обращении к этой странице ваш браузер отправил следующие http-заголовки:
X-Forwarded-Proto: http
Connection: close
User-Agent: CCBot/2.0 (https://commoncrawl.org/faq/)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
If-Modified-Since: Sat, 10 Aug 2024 00:13:59 GMT
Accept-Encoding: br,gzip
Как получить http-заголовки на PHP?
Заголовки, отправляемые сервером
В соответствии со спецификацией http, этот протокол также поддерживает передачу служебной информации от сервера к браузеру, оформленной в виде специальных заголовков.
Таким образом, http headers - это средство общения сервера с удаленным клиентом. Каждый заголовок обычно состоит из одиночной линии ascii текста с именем и значением. Сами заголовки никак не отображаются в окне броузера, но зачастую могут сильно изменить отображение сопутствующего документа.
Механизм отправки http заголовков в php
Механизм отправки заголовков в php представлен функцией header(). Особенность протокола http заключается в том, что заголовок должен быть отправлен до посылки других данных, поэтому функция должна быть вызвана в самом начале документа и должна выглядеть следующим образом:
header("http заголовок"[, replace]);
Необязательный параметр replace может принимать значения (true или false) и указывает на то, должен ли быть заменен предыдущий заголовок подобного типа, либо добавить данный заголовок к уже существующему.
В отношении функции header() часто применяется функция headers_sent(), которая в качестве результата возвращает true в случае успешной отправки заголовка и false в обратном случае.
Рассмотрим наиболее используемые http заголовки.
Cache-control
"cache-control: " значение
Заголовок управления кешированием страниц. Вообще, данная функция является одной из самых распространенных в использовании заголовков.
Данный заголовок может быть использован со следующими значениями:
- no-cache - Запрет кеширования. Используется в часто обновляемых страницах и страницах с динамическим содержанием. Его действие подобно meta тегу "pragma: no-cache".
- public - Разрешение кеширования страницы как локальным клиентом, так и прокси-сервером.
- private - Разрешение кеширования только локальным клиентом.
- max-age - Разрешение использования кешированного документа в течение заданного времени в секундах.
- no-store - Cтраница содержит приватные данные, сохранять в кэше нельзя!
// Кеширование локальными клиентами и использование в течение 1 часа
header("cache-control: private, max-age = 3600");
echo "<h1>", date("H:i:s"), "</h1>";
// кеширования всеми серверами на 1 час
header("Cache-Control: public");
header("Expires: " . date("r", time() + 3600));
echo "<h1>", date("H:i:s"), "</h1>";
Совсем жесткий запрет кеширования на всех этапах:
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Expires: " . date("r"));
echo "<h1>", date("H:i:s"), "</h1>";
Кеширование с помощью файла .htaccess
Expires
"expires: " http-date
Устанавливает дату и время, после которого документ считается устаревшим. Дата должна указываться в следующем формате (на английском языке):
День недели (сокр.) число (2 цифры) Месяц (сокр.) год часы:минуты:секунды gmt
Например, fri, 09 jan 2002 12:00:00 gmt
Текущее время в этом формате возвращает функция gmdate() в следующем виде:
echo gmdate("d, d m y h:i:s")." gmt";
Возможно использование данного http заголовка для запрета кеширования. Для этого необходимо указать прошедшую дату.
Иногда можно встретить и такую комбинацию Expires: now
Last-modified
last-modified: http-date
Указывает дату последнего изменения документа. Дата должна задаваться в том же формате, что и в случае с заголовком expires. Данный заголовок можно не использовать для динамических страниц, так как многие серверы (например, apache) для таких страниц сами выставляют дату модификации.
При запросе это значение передаётся клиентом в специальном заголовке запроса: If-Modified-Since. Обработчик запроса может проверить, изменился ли объект, и если нет - вернуть ответ с пустым телом и кодом ответа 304 Not Modified. Само содержимое страницы не передаётся, и клиент будет использовать то содержимое, которое хранится у него в кэше.
Возможно сделать страницу всегда обновленной:
header("last-modified: ".gmdate("d, d m y h:i:s")." gmt");
Пример использования кеширования с помощью Last-modified
ETag
ETag'и (Entity Tags - тэги сущностей) - механизм, который используют браузеры и веб-сервера, чтобы определить, является ли объект, находящийся в кэше браузера таким же, как соответствующий объект на сервере (а Entity (сущность) - другое название того, что мы называем компонентами: картинки, скрипты и т.д.). Тэги сущностей были задуманы как механизм для определения актуальности сущности в кэше браузера, что является более гибким подходом, нежели проверка по дате последнего изменения (last-modified). ETag - это строка, которая однозначно идентифицирует конкретную версию компонента. Единственное требование: строка должна быть заключена в двойные кавычки. Сервер указывает ETag для компонента используя HTTP-заголовок ETag:
HTTP/1.1 200 OK Last-Modified: Tue, 12 Dec 2006 03:03:59 GMT ETag: "10c24bc-4ab-457e1c1f" Content-Length: 12195
Позднее, если браузер хочет определить актуальность компонента, он передает заголовок If-None-Match для передачи ETag'а обратно на сервер. Если ETag'и совпадают, ответ от сервера приходит со статус-кодом 304, уменьшая таким образом объем передачи на 12195 байт:
GET /i/yahoo.gif HTTP/1.1 Host: us.yimg.com If-Modified-Since: Tue, 12 Dec 2006 03:03:59 GMT If-None-Match: "10c24bc-4ab-457e1c1f" HTTP/1.1 304 Not Modified
Включить ETag для Apache можно, например, следующей директивой:
FileETag MTime SizeОткрючить ETag для Apache:
FileETag none
Location
"location :" абсолютный url
Полезный заголовок, который перенаправляет броузер на указанный адрес. Его действие сравнимо с meta тегом refresh:
header("location: http://htmlweb.ru");
Например, этот заголовок может быть использован так:
if ($login != $admin_login) header("location: http://www.server.com/login.php");
else header("location: http://www.server.com/admin.php?login=$login");
if (!headers_sent()) exit("Произошла ошибка! Пройдите авторизацию заново");
Content-type
Content-type : MIME тип возвращаемого документа
header("Content-type: text/html");
Content-length
Content-length : размер возвращаемого документа
Status
Status : MIME тип возвращаемого документа
Эта директива используется для задания серверу HTTP/1.0 строки-статус, которая будет послана клиенту. Формат: nnn xxxxx, где nnn - 3-х цифровой статус-код, и xxxxx строка причины, например: "Forbidden" (Запрещено). Http-коды статусов.
header("http/1.0 200 Ok");
Content-Encoding
Content-Encoding : gzip
Способность принимать сжатое содержимое клиент отправляет серверу с помощью заголовка Accept-Encoding: gzip. Обычно сервер указывает Accept-Encoding: gzip,deflate.
Range
Задать диапазон скачиваемой информации
header("Range: bytes=1024-");
Разрешить кросс-доменные запросы
header('Access-Control-Allow-Origin: *');
header('Access-Control-Max-Age: 600'); // время в секундах кеширования разрешения
При использовании .htaccess:
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
Подробнее см. http://www.w3.org/TR/cors/#access-control-allow-origin-response-hea
X-XSS-Protection
Атака XSS (межсайтовый скриптинг) это тип атаки, при котором вредоносный код может быть внедрён в атакуемую страницу.
Например вот так:
<h1>Hello, <script>alert('hacked')</script></h1>
Такой тип атаки легко обнаружить и браузер вполне может с этим справиться: если в исходном коде содержится часть запроса, то это может оказаться угрозой.
И заголовок X-XSS-Protection управляет этим поведением браузера.
Принимаемые значения:
- 0 фильтр выключен
- 1 фильтр включен. Если атака обнаружена, то браузер удалит вредоносный код
- 1; mode=block. Фильтр включен, но если атака обнаружится, страница не будет загружена браузером
- 1; report=http://domain/url. фильтр включен и браузер очистит страницу от вредоносного кода, при этом сообщив о попытке атаки. Тут используется функция Chromium для отправки отчёта о нарушении политика защиты контента (CSP) на определённый адрес
Создадим веб сервер-песочницу на node.js, чтобы посмотреть как это работает.
var express = require('express')
var app = express()
app.use((req, res) => {
if (req.query.xss) res.setHeader('X-XSS-Protection', req.query.xss)
res.send(`<h1>Hello, ${req.query.user || 'anonymous'}</h1>`)
})
app.listen(1234)
Буду использовать Google Chrome 55.
Без заголовка
http://localhost:1234/?user=%3Cscript%3Ealert(%27hacked%27)%3C/script%3E
Ничего не произойдёт, браузер успешно заблокирует атаку. Chrome, по умолчанию, блокирует угрозу и сообщает об этом в консоли.
X-XSS-Protection: 0
http://localhost:1234/?user=%3Cscript%3Ealert(%27hacked%27)%3C/script%3E&xss=0
О нет!
X-XSS-Protection: 1
http://localhost:1234/?user=%3Cscript%3Ealert(%27hacked%27)%3C/script%3E&xss=1
Страница была очищена из-за явного указания заголовка.
X-XSS-Protection: 1; mode=block
http://localhost:1234/?user=%3Cscript%3Ealert(%27hacked%27)%3C/script%3E&xss=1;%20mode=block
В этом случае атака будет предотвращена путём блокирования загрузки страницы.
X-XSS-Protection: 1; report=http://localhost:1234/report
http://localhost:1234/?user=%3Cscript%3Ealert(%27hacked%27)%3C/script%3E&xss=1;%20report=http://localhost:1234/report
Атака предотвращена и сообщение об этом отправлено по соответствующему адресу.
X-Frame-Options
При помощи данного заголовка можно защититься от так называемого Кликджекинга [Clickjacking].
Представьте, что у злоумышленника есть канал на YouTube и ему хочется больше подписчиков.
Он может создать страницу с кнопкой «Не нажимать», что будет значить, что все на неё обязательно нажмут. Но поверх кнопки находится абсолютно прозрачный iframe и в этом фрейме прячется страница канала с кнопкой подписки. Поэтому при нажатии на кнопку, на самом деле пользователь подписывается на канал, если конечно, он был залогинен в YouTube.
Продемонстрируем это.
Сперва нужно установить расширение для игнорирования данного заголовка.
Создадим простую страницу.
<style>
button { background: red; color: white; padding: 10px 20px; border: none; cursor: pointer; }
iframe { opacity: 0.8; z-index: 1; position: absolute; top: -570px; left: -80px; width: 500px; height: 650px; }
</style>
<button>Do not click his button!</button>
<iframe src="https://youtu.be/dQw4w9WgXcQ?t=3m33s"></iframe>
Как можно заметить, я разместил фрейм с подпиской прям над кнопкой (z-index: 1) и поэтому если попытаться на неё нажать, то на самом деле нажмётся фрейм. В этом примере фрейм не полностью прозрачен, но это исправляется значением opacity: 0.
На практике, такое не сработает, потому что у YouTube задан нужный заголовок, но смысл угрозы, надеюсь, понятен.
Для предотвращения страницы быть использованной во фрейме нужно использовать заголовок X-Frame-Options.
Принимаемые значения:
- deny не загружать страницу вообще.
- sameorigin не загружать, если источник не совпадает.
- allow-from: ДОМЕН можно указать домен, с которого страница может быть загружена во фрейме.
Нам понадобится веб сервер для демонстрации
var express = require('express')
for (let port of [1234, 4321]) {
var app = express()
app.use('/iframe', (req, res) => res.send(`<h1>iframe</h1><iframe src="//localhost:1234?h=${req.query.h || ''}"></iframe>`))
app.use((req, res) => {
if (req.query.h) res.setHeader('X-Frame-Options', req.query.h)
res.send('<h1>Website</h1>')
})
app.listen(port)
}
Без заголовка
Все смогут встроить наш сайт по адресу localhost:1234 во фрейм.
X-Frame-Options: deny
Страницу вообще нельзя использовать во фрейме.
X-Frame-Options: sameorigin
Только страницы с одинаковым источником смогут встраивать во фрейм. Источники совпадают, если домен, порт и протокол одинаковые.
X-Frame-Options: allow-from localhost:4321
Похоже, что Chrome игнорирует такую опцию, т.к. существует заголовок Content-Security-Policy (о ней будет рассказано ниже). Не работает это и в Microsoft Edge.
X-Content-Type-Options
Данный заголовок предотвращает атаки с подменой типов MIME (<script src="script.txt">) или несанкционированного хотлинка (<script src="https://raw.githubusercontent.com/user/repo/branch/file.js">)
var express = require('express')
var app = express()
app.use('/script.txt', (req, res) => {
if (req.query.h) res.header('X-Content-Type-Options', req.query.h)
res.header('content-type', 'text/plain')
res.send('alert("hacked")')
})
app.use((req, res) => {
res.send(`<h1>Website</h1><script src="/script.txt?h=${req.query.h || ''}"></script>`)
})
app.listen(1234)
Без заголовка
http://localhost:1234/
Хоть script.txt и является текстовым файлом с типом text/plain, он будет запущен как скрипт.
X-Content-Type-Options: nosniff
http://localhost:1234/?h=nosniff
На этот раз типы не совпадают и файл не будет исполнен.
Content-Security-Policy
Это относительно молодой заголовок и помогает уменьшить риски атаки XSS в современных браузерах путём указания в заголовке какие именно ресурсы могут подргружаться на странице.
Например, можно попросить браузер не исполнять inline-скрпиты и загружать файлы только с одного домена. Inline-скрпиты могут выглядеть не только как <script>...</script>, но и как <h1 onclick="...">.
Посмотрим как это работает.
var request = require('request')
var express = require('express')
for (let port of [1234, 4321]) {
var app = express()
app.use('/script.js', (req, res) => {
res.send(`document.querySelector('#${req.query.id}').innerHTML = 'изменено ${req.query.id}-скриптом'`)
})
app.use((req, res) => {
var csp = req.query.csp
if (csp) res.header('Content-Security-Policy', csp)
res.send(`
<html>
<body>
<h1>Hello, ${req.query.user || 'anonymous'}</h1>
<p id="inline">это будет изменено inline-скриптом?</p>
<p id="origin">это будет изменено origin-скриптом?</p>
<p id="remote">это будет изменено remote-скриптом?</p>
<script>document.querySelector('#inline').innerHTML = 'изменено inline-скриптом'</script>
<script src="/script.js?id=origin"></script>
<script src="//localhost:1234/script.js?id=remote"></script>
</body>
</html>
`)
})
app.listen(port)
}
Без заголовка
Это работает так, как вы и ожидали.
Content-Security-Policy: default-src 'none'
http://localhost:4321/?csp=default-src%20%27none%27&user=%3Cscript%3Ealert(%27hacked%27)%3C/script%3E
default-src применяет правило для всех ресурсов (картинки, скрипты, фреймы и т.д.), значение 'none' блокирует всё. Ниже продемонстрировано что происходит и ошибки, показываемые в браузере.
Chrome отказался запускать любые скрипты. В таком случае не получится даже загрузить favicon.ico.
Content-Security-Policy: default-src 'self'
http://localhost:4321/?csp=default-src%20%27self%27&user=%3Cscript%3Ealert(%27hacked%27)%3C/script%3E
Теперь можно использовать ресурсы с одного источника, но по прежнему нельзя запускать внешние и inline-скрипты.
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'
http://localhost:4321/?csp=default-src%20%27self%27;%20script-src%20%27self%27%20%27unsafe-inline%27&user=%3Cscript%3Ealert(%27hacked%27)%3C/script%3E
На этот раз мы разрешили исполнение и inline-скриптов. Обратите внимание, что XSS атака в запросе тоже была заблокирована. Но этого не произойдёт, если одновременно поставить и unsafe-inline, и X-XSS-Protection: 0.
Другие значения
На сайте content-security-policy.com красиво показаны множество примеров.
- default-src 'self' разрешит ресурсы только с одного источника
- script-src 'self' www.google-analytics.com ajax.googleapis.com разрешит Google Analytics, Google AJAX CDN и ресурсы с одного источника.
- default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self'; разрешит изображения, скрипты, AJAX и CSS с одного источника и запретит загрузгу любых других ресурсов. Для большинства сайтов это хорошая начальная настройка.
Я этого не проверял, но я думаю, что следующие заголовки эквиваленты:
- frame-ancestors 'none' и X-Frame-Options: deny
- frame-ancestors 'self' и X-Frame-Options: sameorigin
- frame-ancestors localhost:4321 и X-Frame-Options: allow-from localhost:4321
- script-src 'self' без 'unsafe-inline' и X-XSS-Protection: 1
Если взглянуть на заголовки facebook.com или twitter.com, то можно заметить, что эти сайты используют много CSP.
Strict-Transport-Security
HTTP Strict Transport Security (HSTS) это механизм политики безопасности, который позволяет защитить сайт от попытки небезопасного соединения.
Допустим, что мы хотим подключиться к facebook.com. Если не набрать перед запросом https://, то протокол, по умолчанию, будет выбран HTTP и поэтому запрос будет выглядеть как http://facebook.com.
$ curl -I facebook.com
HTTP/1.1 301 Moved Permanently
Location: https://facebook.com/
После этого мы будем перенаправлены на защищённую версию Facebook.
Если подключиться к публичной WiFi точке, которая принадлежит злоумышленнику, то запрос может быть перехвачен и вместо facebook.com злоумышленник может подставить похожую страницу, чтобы узнать логин и пароль.
Чтобы обезопаситься от такой атаки, можно использовать вышеупомянутый заголовок, который скажет клиенту в следующий раз использовать https-версию сайта.
$ curl -I https://www.facebook.com/
HTTP/1.1 200 OK
Strict-Transport-Security: max-age=15552000; preload
Если пользователь был залогинен в Facebook дома, а потом попытался открыть его из небезопасной точки доступа, то ему ничего не угрожает, т.к. браузеры запоминают этот заголовок.
Но что будет, если подключиться в небезопасной сети первый раз? В этом случае защититься не получится.
Но у браузеров есть козырь и на этот случай. В них есть предопределённый список доменов, для которых следует использовать только HTTPS.
Можно отправить свой домен по этому адресу. Там также можно узнать правильно ли используется заголовок.
Принимаемые значения:
- max-age=15552000 время, в секундах, которое браузер должен помнить о заголовке.
- includeSubDomains Если указать это опциональное значение, то заголовок распространяется и на все поддомены.
- preload если владелец сайта хочет, чтобы домен попал в предопределённый список, поддерживаемый Chrome (и используемый Firefox и Safari).
А если потребуется переключиться на HTTP перед сроком истечения max-age или если установлен preload? Можно поставить значение max-age=0 и тогда правило перехода на https версию работать перестанет.
Public-Key-Pins
HTTP Public Key Pinning (HPKP) это механизм политики безопасности, который позволяет HTTPS сайтам защититься от использования злоумышленниками поддельных или обманных сертификатов.
Принимаемые значения:
- pin-sha256="<sha256>" в кавычках находится закодированный с помощью Base64 отпечаток Subject Public Key Information (SPKI).
Можно указать несколько пинов для различных открытых ключей. Некоторые браузеры в будущем могут использовать и другие алгоритмы хеширования, помимо SHA-256.
- max-age=<seconds> время, в секундах, которое браузер запоминает что для доступа к сайту нужно использовать только перечисленные ключи.
- includeSubDomains если указать этот необязательный параметр, то заголовок действует и на все поддомены.
- report-uri="<URL>" если указать URL, то при ошибке проверки ключа, соответствующее сообщение отправится по указанному адресу.
Вместо заголовка Public-Key-Pins можно использовать Public-Key-Pins-Report-Only, в таком случае будут отправляться только сообщения об ошибках совпадения ключей, но браузер всё равно будет загружать страницу.
Так делает Facebook:
$ curl -I https://www.facebook.com/
HTTP/1.1 200 OK
...
Public-Key-Pins-Report-Only:
max-age=500;
pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=";
pin-sha256="r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=";
pin-sha256="q4PO2G2cbkZhZ82+JgmRUyGMoAeozA+BSXVXQWB8XWQ=";
report-uri="http://reports.fb.com/hpkp/"
Зачем это нужно? Не достаточно ли доверенных центров сертификации (CA)?
Злоумышленник может создать свой сертификат для facebook.com и путём обмана заставить пользователя добавить его в своё хранилище доверенных сертификатов, либо он может быть администратором.
Попробуем создать сертификат для facebook.
sudo mkdir /etc/certs
echo -e 'US\nCA\nSF\nFB\nXX\nwww.facebook.com\nno@spam.org' | \
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/certs/facebook.key \
-out /etc/certs/facebook.crt
И сделать его доверенным в локальной системе.
# curl
sudo cp /etc/certs/*.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
# Google Chrome
sudo apt install libnss3-tools -y
certutil -A -t "C,," -n "FB" -d sql:$HOME/.pki/nssdb -i /etc/certs/facebook.crt
# Mozilla Firefox
#certutil -A -t "CP,," -n "FB" -d sql:`ls -1d $HOME/.mozilla/firefox/*.default | head -n 1` -i /etc/certs/facebook.crt
А теперь запустим веб-сервер, использующий этот сертификат.
var fs = require('fs')
var https = require('https')
var express = require('express')
var options = {
key: fs.readFileSync(`/etc/certs/${process.argv[2]}.key`),
cert: fs.readFileSync(`/etc/certs/${process.argv[2]}.crt`)
}
var app = express()
app.use((req, res) => res.send(`<h1>hacked</h1>`))
https.createServer(options, app).listen(443)
Переключимся на сервер
echo 127.0.0.1 www.facebook.com | sudo tee -a /etc/hosts
sudo node server.js facebook
Посмотрим что получилось
$ curl https://www.facebook.com
<h1>hacked</h1>
Отлично. curl подтверждает сертификат.
Так как я уже заходил на Facebook и Google Chrome видел его заголовки, то он должен сообщить об атаке но разрешить страницу, так?
Неа. Ключи не проверялись из-за локального корневого сертификата [Public-key pinning bypassed]. Это интересно…
Хорошо, а что насчёт www.google.com?
echo -e 'US\nCA\nSF\nGoogle\nXX\nwww.google.com\nno@spam.org' | \
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/certs/google.key \
-out /etc/certs/google.crt
sudo cp /etc/certs/*.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
certutil -A -t "C,," -n "Google" -d sql:$HOME/.pki/nssdb -i /etc/certs/google.crt
echo 127.0.0.1 www.google.com | sudo tee -a /etc/hosts
sudo node server.js google
Тот же результат. Думаю это фича.
Но в любом случае, если не добавлять эти сертификаты в локальное хранилище, открыть сайты не получится, потому что опции продолжить небезопасное соединение в Chrome или добавить исключение в Firefox не будет.
Content-Encoding: br
Данные сжаты при помощи Brotli.
Алгоритм обещает лучшее сжатие чем gzip и сравнимую скорость разархивирования. Поддерживается Google Chrome.
Разумеется, для него есть модуль в node.js.
var shrinkRay = require('shrink-ray')
var request = require('request')
var express = require('express')
request('https://www.gutenberg.org/files/1342/1342-0.txt', (err, res, text) => {
if (err) throw new Error(err)
var app = express()
app.use(shrinkRay())
app.use((req, res) => res.header('content-type', 'text/plain').send(text))
app.listen(1234)
})
Исходный размер: 700 Кб
Brotli: 204 Кб
Gzip: 241 Кб
Timing-Allow-Origin
С помощью Resource Timing API можно узнать сколько времени заняла обработка ресурсов на странице.
Поскольку информация о времени загрузки может быть использована чтобы определить посещал ли пользователь страницу до этого (обращая внимание на то, что ресурсы могут кэшироваться), стандарт считается уязвимым, если давать такую информацию любым хостам.
<script>
setTimeout(function() {
console.log(window.performance.getEntriesByType('resource'))
}, 1000)
</script>
<img src="http://placehold.it/350x150">
<img src="/local.gif">
Похоже, если не указать Timing-Allow-Origin, то получить детальную информацию о времени операций (поиска домена, например) можно только для ресурсов с одним источником.
Использовать можно так:
- Timing-Allow-Origin: *
- Timing-Allow-Origin: http://foo.com http://bar.com
Alt-Svc
Альтернативные Сервисы [Alternative Services] позволяют ресурсам находиться в различных частях сети и доступ к ним можно получить с помощью разных конфигураций протокола.
Такой используется в Google:
- alt-svc: quic=":443"; ma=2592000; v=«36,35,34»
Это означает, что браузер, если захочет, может использовать QUIC, это HTTP над UDP, через порт 443 следующие 30 дней (ma = 2592000 секунд, или 720 часов, т.е 30 дней). Понятия не имею что означает параметр v, версия?
P3P
Ниже несколько P3P заголовков, которые я встречал:/p>
- P3P: CP=«This is not a P3P policy! See support.google.com/accounts/answer/151657?hl=en for more info.»
- P3P: CP=«Facebook does not have a P3P policy. Learn why here: fb.me/p3p»
Некоторые браузеры требуют, чтобы cookies третьих лиц поддерживали протокол P3P для обозначения мер конфиденциальности.
Организация, основавшая P3P, Консорциум Всемирной паутины (W3C), приостановила работу над протоколом несколько лет назад из-за того, что современные браузеры не до конца поддерживают протокол. В результате, P3P устарел и не включает в себя технологии, которые сейчас используются в сети, поэтому большинство сайтов не поддерживают P3P.
Пример использования gzip-сжатия
.
Прокомментировать/Отблагодарить