header

Запрос HEAD, заголовки Header

По сути метод HEAD — это то же самое, что и метод GET, за исключением: в ответ на запрос методом head сервер возвращает только заголовки из самого содержания. Т.е. если мы хотим посмотреть, какие заголовки сервер вернет при запросе данной страницы, а сама страница не нужна, используем метод HEAD. Заголовки, которые возвращаются сервером, мы можем менять (кроме заголовка Server, Date). Можем допослать те заголовки, которые сервер не посылает (он не знает, что их нужно послать). Может также поменять значение заголовка.

Header: location и refresh

Все заголовки посылаются функцией header (имя заголовка: значение). ОБЯЗАТЕЛЬНО все заголовки посылаются до любого вывода. Примеры заголовков:

header("Location: example.php"); // куда идти,редирект на этот файл
header ("Refresh: 5"); // перезагрузка браузера через 5 секунд
header("Refresh:5; url=http://levevg.ru/index.php"); // редирект на другой сайт через 5 секунд

Когда браузер видит заголовок Location, он все бросает и идет выполнять инструкцию. Представим ситуацию: на сайте форма для отправки данных методом post. Пользователь заполнил форму, нажал отправить, данные ушли. Затем опять нажал F5 или Refresh (обновить страницу), данные снова ушли. В итоге в базе получается несколько одинаковых записей (или на форуме несколько одинаковых сообщений). Но если использовать Location, повторная отправка данных не произойдет. Желательно после использования Location остановить выполнение кода с помощью exit, т.е. после этого заголовка код дальше не выполняется, страница перезапрашивается. И получается, что php вхолостую будет отрабатывать код (хотя он уже получил новую страницу через location для обработки).

Header: content-type

Всегда браузер не отслеживает, что мы запрашиваем. Например, запросили файл exe.php. Браузеру ‘до лампочки’, что это за файл, браузер смотрит в заголовок content-type. Если браузеру отдать файл .gif, а в заголовке написать, что это .jpeg, он поверит, что этот файл .jpeg, и попытается его отобразить как jpeg => ничего не получится. Примеры:

header("Content-type: text/xml");
header("Content-type:text/html;charset=windows-1251"); //Отдаем файл пользователю, задаем кодировку
header("Content-type: text/plain");
header("Content-Disposition:attachment;filename=\"myfile.txt\""); //Вывод содержимого файла

На каждом сервере написано, какому типу файлов соответствует какое расширение (html => text/html). Сервер, какое расширение получил через заголовок content-type, таким образом и вывел файл. Он никогда не заглядывает во внутрь файла, не анализирует его. Сервер никогда не передает кодировку этого файла. А браузер, получая данный файл без кодировки, пытается угадать, какая это кодировка. Поэтому задавать кодировку нужно обязательно в заголовке. Есть некоторые админы серверов, которые принудительно выставляют кодировку (типа народ.ру). В основном это бесплатный хостинг. Выставлять кодировку мы можем в мета-теге, но приоритетнее будет то, что приходит с сервера:

<meta http-equiv-"Content-Type" content-"text/html;charset=utf-8">

Данный мета-тег вообще не нужен. Все нормальные сервера посылают нужную информацию через заголовок header:content-type. Когда в браузер попадает запрашиваемая страница, он может ее не только вывести на экран перед нами, но и перенаправить в любое другое место. Например, браузер может запустить любую программу и отдать этот код программе на выполнение; или создать файл и направить исполняемый код страницы в этот файл. Это можно сделать при помощи следующего кода:

header("Content-Type:file/octet-stream"); // указание типа файла
header("Content-disposition:attachment; filename-\"example.txt\""); // предлагаем имя файла

При выполнении кода браузер предложит открыть/сохранить файл. При этом файла example.txt не существует. Т.е. не все, что мы скачиваем, существует физически.

Header: Cache-Control и Expires

Десяток лет назад скорости интернета были маленькие, трафик дорогой, все работало медленно. И придумали: зачем каждый раз файл брать с сервера, если он меняется раз в месяц или раз в год; хорошо бы его сохранить у клиента, и браузер его каждый бы раз показывал. А поскольку данный файл перезапрашивать нужно (вдруг он изменился), то сохранять файл у клиента какое-то время. И придумали заголовки cache-control для кэширования, expire — срок, на сколько кэшировать файл.

Со временем появились новостные сайты, информация на которых обновляется несколько раз в день. И начали запрещать кэширование. А браузер по-умолчанию, кэширует весь контент. И началась война с кэшированием. Понятно, что в этом деле нужен обдуманный подход. Есть вещи, которые не надо кэшировать (например, новостная лента), а есть те, которые лучше кэшировать (например, стилевые файлы, ява-скрипты, картинки).

Для запрета кэширования есть много заблуждений. В той же википедии советуют:

Header заголовки

Заголовок Expires говорит об актуальности, насколько эта страница актуальна. Заголовок Last-Modified — когда статья была изменена. ПРИМЕР: Браузер закэшировал страницу, а актуальная дата стоит на вчера, браузер взял да и удалил страницу из кэша. Поисковый робот проиндексировал нашу страницу; думает, когда зайти в следующий раз. Смотрит на актуальность, а там — вчерашняя дата. Робот заходит завтра, смотрит актуальность страницы, а там снова — вчера. Робот ‘офигевает’ (авт.). И сайт теряет позиции в поисковой выдаче. Поэтому всегда используйте в данном заголовке текущую дату.

Браузер, получив весь этот код выше, закэширует все, что ему нужно. В данном коде юзер вредит себе дважды, особенно с точки зрения поисковиков. В третьей строке используется cache-controle:no-cache — браузера этот код никак не касается. Это не запрет кэширования. По сути этот код означает: ты можешь закэшировать, но перед тем, как поднять из кэша, ты должен узнать, не обновилась ли эта страница там. Помните, кэшируются не только страницы, но и запросы.

В реальности запрет на кэширование можно записать так:

header("Cache-Control: no-store"); // явный запрет кэширования
header("Cache-Control: no-store,no-cache,must-revalidate"); // иногда используют
header("Expires: " . date("r")); // как должна посылаться дата

Как разрешить кэширование:

header("Cache-Control: public");
header("Expires: " . date("r", time()+3600));

Header: Set-Cookie

Файлы cookies можно послать и заголовком.

header("Set-Cookie: name=Max; expires=Wed, 30 Sep 12 11:49:14 GMT");

Когда мы заходим в электронную почту, вводим логин-пароль, выскакивает сообщение: запомнить меня на этом компьютере. Нам летят cookies (логин и пароль). Пароль должен быть зашифрован. И в своей базе данных, когда мы регистрируем пользователя, пароли надо шифровать. Для этого есть много методов. Самый популярный алгоритм — это MD5.

В php для этого алгоритма есть функция — md5 (string). Любой алгоритм шифрования подразумевает зашифровку и расшифровку пароля. Поэтому точнее — это хэш-функция. Т.е. это односторонее шифрование: зашифровать можно, а расшифровать нельзя. Передавая строку в md5, мы получим абракадабру:

md5("888");
//0a113ef6b61820daa5611c870ed8d5ee
md5("Vasya");
//96932f68a34ac08a6c92ed8db20d2ee3
md5("MeGaPa$$w0rd");
//bfb5a5275a34cf74cdfebdea0cf9c421

Одна и та же строка имеет один и тот же хэш. В этом случае, если мы посылаем cookies, мы посылаем в виде пароля этот хэш.

Многие сайты хранят в базе данных пароли в открытом виде. Взломали базу, все пароли ушли. Можно проверить это. Когда регистрируетесь на сайте, там есть ссылка — забыл свой пароль. Если придет письмо, и там будет пароль в открытом виде, значит он открыто лежит в базе данных.

Но даже если пароль зашифрован в md5, его можно взломать с помощью радужных таблиц. Об этом в другой статье.




Добавить комментарий

Ваш e-mail не будет опубликован.