Архив за Октябрь 2008

Работа с cookies. Часть 2

Установка cookie

Установка cookie-наборов средствами JavaScript равнозначна установке свойства cookie объекта document. При этом очень важно использовать тот же самый формат протокола HTTP, что и при отправке cookie-набора клиенту. В обычных cookie-наборах, т.е. таких наборах, у которых отсутствует срок действия или другие ограничения, имя и значение cookie должны ббыть разделены знаком равенства. Кроме того, в имени cookie не должно быть таких специальных сиволов, как пробелы и точки с запятой. Специальные символы в значении cookie должны быть закодированы в формате URL, например, пробел обозначается как %20, т.е. в шестнадцатеричном представлении его кода ASCII.

Как показано в приведенном ниже листинге, для установки нескольких cookie достаточно задать соответствующее число значений свойства document.cookie. Следовательно, запись очередного значения в свойстве document.cookie не приводит к перезаписи всех предыдущих cookie, а лишь к добавлению еще одного cookie. Единственное исключение из этого правила: если cookie с этим же именем уже существует, клиент попытается перезаписать его.

<script type="text/javascript">
document.cookie = "myLanguage=JavaScript";
document.cookie = "myOtherLanguage=PHP:%20Hypertext%20Preprocessor"
</script>

Чтение cookie

При доступе к свойству document.cookie в коде JavaScript извлекается список всех cookie, которые браузер должен отправить обратно текущему серверу. К сожалению, такой доступ возможен только в формате строки, но не массива. Например, приведенный выше пример кода формирует следующее значение свойства document.cookie:

myLanguage=JavaScript;myOtherLanguage=PHP:%20Hypertext%20Preprocessor

Следовательно, для того, чтобы извлечь cookie из этого значения, необходимо предпринять определенные шаги.

  1. Разделить строку cookie по символу “;”, чтобы получить отдельные cookie.
  2. Определить первый знак равенства (=) в каждом cookie в качестве разделителя имени и значения.

Значения cookie могут содержать знаки равенства, поэтому следует использовать первре вхождение знака равенства. В следующем фрагменте кода выводятся все cookie в форме HTML-таблицы.

<script type="text/javascript">
document.write("<table><tr><th>Name</th><th>Value</th></tr>");
var cookies = document.cookie.split(/; /g);
for (var i=0; i<cookies.length; i++) {
  var cookie = cookies[i];
  if (cookie.indexOf("=") == -1) {
    continue;
  }
  var name = cookie.substring(0, cookie.indexOf("="));
  var value = cookie.substring(cookie.indexOf("=") + 1);
  document.write("<tr><td>" +
                 HtmlEscape(name) +
                 "</td><td>" +
                 HtmlEscape(unescape(value)) +
                 "</td></tr>");
}
document.write("</table>");

function HtmlEscape(s) {
  return s.replace(/&/, "&amp;")
          .replace(/</, "&lt;")
          .replace(/>/, "&gt;")
          .replace(/"/, "&quot;")
          .replace(/'/, "
&apos;");
}
</script>

Если же требуется значение одного конкретного cookie, для этой цели можно использовать приведенную ниже вспомогательную функцию. Эта функция осуществляет поиск заданного имени cookie и возвращает его значение, т.е. все, что находится справа от имени cookie вплоть до следующей точки с запятой или конца строки.

<script type="text/javascript">
function getCookie(name) {
  var pos = document.cookie.indexOf(name + "=");
  if (pos == -1) {
    return null;
  } else {
    var pos2 = document.cookie.indexOf(";", pos);
    if (pos2 == -1) {
      return unescape(
        document.cookie.substring(pos + name.length + 1));
    } else {
      return unescape(
        document.cookie.substring(pos + name.length + 1, pos2));
    }
  }
}

alert(getCookie("myLanguage"));
alert(getCookie("myOtherLanguage"));
</script>

Создание RSS-ленты новостей

Формат RSS фактически является XML-форматом, а значит мы можем использовать возможности расширения DOM для создания RSS-ленты. Приведенный ниже код расширяет класс DOMDocument, чтобы построить дерево DOM, создавая элементы и добавляя их в соответствующую структуру.

<?php
class rss2 extends DOMDocument {
  private $channel;
 
  public function __construct($title, $link, $description) {
    parent::__construct();
    $this->formatOutputtrue;
   
    $root = $this->appendChild($this->createElement('rss'));
    $root->setAttribute('version', '2.0');
   
    $channel = $root->appendChild($this->createElement('channel'));
   
    $channel->appendChild($this->createElement('title', $title));
    $channel->appendChild($this->createElement('link', $link));
    $channel->appendChild($this->createElement('description', $description));
   
    $this->channel = $channel;
  }
 
  public function addItem($title, $link, $description) {
    $item = $this->createElement('item');
    $item->appendChild($this->createElement('title', $title));
    $item->appendChild($this->createElement('link', $link));
    $item->appendChild($this->createElement('description', $description));
    $this->channel->appendChild($item);
  }
}
?>

Конструктор класса создает и инициализирует элементы <rss> и <channel>. Он принимает три аргумента: название канала, ссылку и описание. Конструктор вызывает метод parent::__construct(), что фактически приводит к вызову метода DOMDocument::__construct(). После этого можно приступать к построению документа.

Сперва устанавливаем атрибут formatOutput в значение true. В вывод будут добавлены отступы и символы перевода строки, так что его будет легче читать.

Затем создаем корневой элемент документа, т.е rss, и устанавливаем атрибут version в значение 2.0, потому как мы строим ленту новостей формата RSS 2.0.

Все данные будут находиться внутри элемента channel под узлом rss, поэтому следующий шаг - создание этого элемента и инициализации его элементов-потомков title, link и description.

Все эти данные берутся из аргументов, переданных конструктору. Они создаются методом CreateElement(), который позволяет указать как имя элемента, так и текстовой узел за один вызов.

Наконец, сохраняем элемент channel, чтобы упростить обращение к нему в дальнейшем.

Для добавления новых статей предназначен метод addItem(). Поскольку элементы item содержат те же данные, что и channel, код метода addItem() почти идентичен коду конструктора.

Пример использования класса:

<?php
$dblocation = 'localhost';   // Имя сервера
$dbuser     = 'root';        // Имя пользователя
$dbpswrd    = '';            // Пароль
$dbname     = 'mydb';        // Имя базы данных

// Соединение с сервером базы данных
$dblink = mysql_connect( $dblocation, $dbuser, $dbpswrd );
mysql_query( 'SET NAMES UTF8' );
// Выбираем базу данных
mysql_select_db( $dbname, $dblink );

$rss = new rss2('Новости по системам безопасности', 'http://sec-news.ru',
                'Российские новости по техническим средствам и системам безопасности
                (видеонаблюдение, контроль доступа, охранно-пожарная сигализация)'
);

$query = 'SELECT id, title, announce
          FROM news
          ORDER BY puttime DESC
          LIMIT 10'
;
$res = mysql_query( $query );
               
while( $news = mysql_fetch_array( $res ) ) {
  $rss->addItem($news['title'], 'http://sec-news.ru/news/'.$news['id'].'/', $news['announce']);
}

echo $rss->saveXML();
?>

Проверить отображение сайта в разных браузерах

Мы не можем знать, каким браузером пользуется очередной посетитель нашего сайта, а различия в обработке HTML/CSS кода столь велики, чтобы нельзя просто игнорировать их. Практически невозможно помнить обо всех возможных проблемах: детальное тестирование в различных браузерах — это единственный способ обеспечить нормальное функционирование сайта. Если у вас нет нужного браузера, то вы можете найти практически любой на сайте browsers.evolt.org.

В Windows предусмотрена возможность установки только одной версии Internet Explorer, но, чтобы гарантировать правильное отображение сайта в наиболее популярных браузерах, нам нужно как минимум IE6 и IE7. Microsoft предлагает использовать Virtual PC, чтобы запускать браузеры одновременно, но есть и более простое решение: multiple versions of IE от TredoSoft позволяет установить на компьютер несколько версий IE.

Браузеры установленные таким образом работают не очень устойчиво и иногда падают без видимых причин, но, несмотря на это, свои задачи пакет выполняет в полном объеме. Установщик работает в Windows XP, пользователям Windows Vista придется использовать Virtual PC.

Есть ещё один инструмент: IETester — бесплатный браузер, который позволяет тестировать страницы в IE8 beta 2, IE7, IE6 и IE5.5 на Vista и XP.

Для тестирования также можно использовать специальные онлайновые сервисы, показывающие скриншот вашего сайта в разных браузерах.