программирование

PDF в Safari — картинка

Браузер «Сафари» под «Мак», оказывается, умеет отображать PDF (и TIFF, кстати, тоже) в теге IMG. Т. е. как простую картинку. Поскольку в OSX есть встроенная поддержка PDF, такое поведение браузера, видимо, вытекает из того, что картинки в браузере отображаются через какой-то системный компонент. Причём, с отображением PDF через тег OBJECT у «Сафари» есть проблемы, если только не установить специальный плагин от фирмы Adobe.

А вот браузер «Опера», помимо стандартного набора JPEG/PNG/GIF/XBM умеет отображать ещё и ICO. Почему этого не делают остальные браузеры — загадка, ведь им всё равно приходится работать с этим форматом, чтобы отобразить favicon.ico.

Оставить комментарий

Оптимизация MySQL InnoDB

Давно хотел записать, чтобы не потерять. Выдержка из главы «Defragmenting a Table» руководства по MySQL:

It can speed up index scans if you periodically perform a “null” ALTER TABLE operation: ALTER TABLE tbl_name ENGINE=INNODB

That causes MySQL to rebuild the table. Another way to perform a defragmentation operation is to use mysqldump to dump the table to a text file, drop the table, and reload it from the dump file.

По-русски говоря, таблицы в формате InnoDB могут сильно фрагметироваться в процессе работы, для того, чтобы избавиться от фрагметрации выполняйте иногда это «магическую» конструкцию или снимайте дамп с таблицы и заливайте обратно.

Пример скрипта для автоматической дефрагментации — дальше.

mysql_connect('localhost', 'root', 'пароль');

$res = mysql_query('SHOW DATABASES');

while (list($dbname) = mysql_fetch_row($res))
{
        mysql_select_db($dbname);

        $rec = mysql_query('SHOW TABLE STATUS');

        while ($data = mysql_fetch_object($rec))
        if ($data->Engine == 'InnoDB')
        {
                echo 'Processing ', $dbname, '.', $data->Name, ' ... '; flush();

                mysql_query("ALTER TABLE {$data->Name} ENGINE=InnoDB");

                echo "done.n";
        }

        mysql_free_result($rec);
}

mysql_free_result($res);

P.S. Как справедливо заметил Jimi Dini, в MySQL 5.0 и выше OPTIMIZE TABLE делает то же самое для InnoDB.

9 комментариев

Тег VIDEO в новой «Опере»

Последний экспериментальный билд «Оперы» (ни в коем случае не устанавливайте его поверх вашей рабочей версии — эта версия основана на одной из альфа-версий Opera 9.50) поддерживает новый тег VIDEO, который входит в предварительную версию стандарта HTML5. Пока в качестве формата видео для этого тега выбран бесплатный Ogg Theora (кстати, недавно я писал о веб-камере, где всё ПО пишется под лицензией GNU, там используется тот же формат). Так же этом билде «Оперы» есть возможность использовать тег VIDEO внутри SVG.

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

Самое простое использование тега VIDEO — указание в атрибуте SRC видеофайла, который он должен проиграть и атрибута controls, который указывает должен ли браузер показывать кнопки управления воспроизведением (или разработчик будет управлять видео через соответствующие JavaScript-методы — play, pause, stop). В статье на сайте разработчиков есть несколько примеров.

VIDEO в HTML5 (42.16КиБ)

Стандартные элементы управления (на рисунке) меня совершенно не впечатлили, я бы их использовать не стал, впрочем, дизайн ещё может измениться, да и всегда есть возможность сделать свои кнопки через JavaScript. Больше всего меня поразили методы внедрения видео в SVG — на сайте есть очень несложные в реализации примеры отражения шарика, движущегося внутри видео, в поверхности, наложения на видео фильтров (в примерах — trace edges, grayscale) и клиппинга.

P.S. На домашней странице Chris Double есть ссылки на FireFox3.0alpha9, собранный с поддержкой тега VIDEO.

Оставить комментарий

Редирект в ASP.NET

Есть тут специалисты в ASP.NET? Скажите, это единственный способ сделать редирект, используя эту замечательную технологию?

<configuration>
<system.web>
<urlMappings enabled="true">
<add url="~/Article28.aspx" mappedUrl="~/MyNewBestArtile.aspx"/>
<urlMappings>
</system.web>
</configuration>

P.S. Александр Семёнов из «ICL» уже подсказал, что есть возможность сделать просто «Response.Redirect», а приведённый выше кусок, по всей видимости, простой аналог «mod_rewrite» из веб-сервера «Apache».

3 комментария

Min-width в IE6 без JavaScript

Для меня оказалось сюрпризом, что min-width в Internet Explorer 6 и ниже можно эмулировать стилями, без обычного, в данном случае, JavaScript (в IE7 min-width работает). Оцените фокус:

CSS-файл:

/* min-width для остальных браузеров */
body {margin:0;padding:0;}
.outer {
  background-color:red;
  margin:0 auto;
  min-width:600px
}

/* стили для IE6 */
* html .outer {padding-left:600px}
* html .minwidth {height:0} /* holy hack для IE, что бы включить свойство hasLayout */
* html .container {margin-left:-600px;position:relative; height:0}

HTML:

<div class="outer">
<div class="minwidth">
<div class="container">
Блок с min-width 600 пикселей.
</div>
</div>
</div>

Первоисточником решения, по всей видимости, является статья Stu Nicholls на сайте CSSPlay.

8 комментариев

Перенос и FireFox

Как известно — FireFox последний из браузеров, который не поддерживает мягкий перенос (shy). Explorer, как один из продвинутых браузеров (не надо смеяться, я не шучу), начал его поддерживать самым первым. Мягким переносом верстальщик может указать где в длинном слове, при необходимости, можно сделать перенос, например, если слово не умещается в колонку. Я прочитал несколько статей на эту тему, но нигде эту задачу решить не смогли. Между тем, в FireFox действует нестандартный тег WBR, который позвляет добиться того же самого, но без символа переноса. Что не совсем то. Кстати, CSS применить к WBR нельзя. Как же быть?

Проблему я решил, но, увы, с потерями: придётся подбирать один параметр для каждого вида шрифта, слово разорванно тегом и поисковые машины проиндексируют его по частям, а полный (совместимый с Opera, FF и IE6) вариант довольно громоздок.

Во-первых, я сразу отказался от тега WBR, потому что любой HTML-валидатор укажет на то, что тег нестандартный. В FireFox действует Zero-width space, символ с кодом 8203, «пробел нулевой ширины». Он позволяет добиться того же самого — разорвать слово в определённом месте.

С идеей как это всё реализовать, я определился сразу — строка при переносе должна открывать концевой символ. А, если переноса нет, вставать поверх него. Вдоволь помучавшись с перекрытием через «position: absolute», и селектором «:after», я вдруг вспомнил о теге «Q», где можно указать текст перед и после этого тега (вообще-то указываются там открывающая и закрывающая кавычка, но сути-то это не меняет). Стало значительно проще. Для того, чтобы один символ затёр другой без остатка, я применяю «background: inherit» — наследуя фон из тегов выше.

Итак, один из минусов — это размер символа переноса в вашем экранном шрифте. Задаётся он в стиле (см. ниже) в параметре «margin-right» и для выбранной мной Tahoma равен 0.36em. Полный пример, работающий в FireFox таков (я выбрал «заброшенный» тег «VAR», чтобы реализовать задуманное):

<!-- Soft hyphen emulation in FireFox -->
<style type="text/css">
    body { background: white }
    var>q { quotes: "" "-"; margin-right: -0.36em }
    var { font-style: normal; background: inherit }
</style>

<var><q>оченьдлинноеслово&#8203;<var>продолжениеоченьдлинногослова</var></var>

Стоит браузеру разорвать слово в месте, где стоит пробел нулевой ширины и из-под второй половины слова появляется символ переноса. С полным вариантом всё немного сложнее — в Opera всё будет работать и так, в IE — нет. Там масса проблем — символ не будет перекрываться фоном, даже если вынести символ переноса из «Q» в текст, но можно заставить работать «shy». Для этого придётся убрать нулевой пробел, если его оставить в IE рядом с «shy», эффект будет непредвиденным.

Поэтому мы его убираем (кстати, можно попытаться вставить его через атрибут «content» селектором «var>var:before», если текст у нас в Unicode):

<!-- Soft hyphen in FireFox, Opera, IE6 -->
<style type="text/css">
    body { background: gray; font-size: 20px; font-family: Tahoma }
    var>q { quotes: "" "-"; margin-right: -0.36em }
    var { font-style: normal; background: inherit }
    * html var b { display: none }
</style>
<var><q>оченьдлинноеслово<b>&#8203;</b>&shy;<var>продолжениеоченьдлинногослова</var></var>

2 комментария

Неуловимый тег HYPE

Разбирая заметки сайта за 2000—2003 гг. (всё думаю — конвертировать их или не нужно), наткнулся на старую заметку, где я пытался разобраться с недокументированными тегами браузеров. На тот момент актуальными были Internet Explorer и, почивший ныне, Netscape Navigator (другой браузер под тем же именем зачем-то до сих пор выпускает AOL). Оказалось, что, по меньшей мере, один из «секретных» тегов браузера от Netscape дожил до наших дней — это HYPE.

Его до сих пор можно найти в исходниках ядра Gecko и, соответсвенно, он работает в браузерах, основанных на этом ядре. Основное его назначение туманно, по всей видимости, он должен выводить какую-то картинку и играть мелодию, но только на платформах Unix и Mac:

The hype tag is just for fun. It only effects the UNIX version which can affor to have a sound file compiled into the binary. If we have the memory, create a fake image tag to replace the <HYPE> tag and process it.

Легко убедиться, что тег присутствует, если попробовать в FireFox повесить на него любой CSS стиль. Кстати, тег таким же образом «работает» и в Опере, потому что (и это оказалось для меня большим сюрпризом) в Опере можно использовать любое сочетание букв в качестве тега. Самая старая Опера, которая у меня есть на компьютере — 8.02 прекрасно отобразила красный бордюр вокруг свежеизобретённого мной тега «REDBORDER» со стилем «background: 1px solid red».

Я думаю, что тег, возможно, не совсем бесполезен, так как Internet Explorer за тег его не считает. Возможно, таким образом можно применять CSS к какому-то блоку, незаметно для Internet Explorer или скрывать от него часть контента (применяя «display: none» на тег HYPE).

Оставить комментарий

Robots.txt для роботов?

На блоге «ODP (DMOZ) неофициально» нашёл ссылку на больше забавное, чем полезное исследование на тему применения файла robots.txt.

Andrew Wooster прошёлся скриптом, написанным на Python, по известнейшему каталогу DMOZ и скачал все robots.txt сайтов, которые там зарегистрированы. Получилась достаточно большая база — 12Гб (около 4,6 миллиона доменов). Бо́льшая часть сайтов (чуть больше 65%) этого файла не имеют, что ожидаемо, вот у меня, например, его тоже нет, у меня нечего запрещать к индексированию.

В остальной части встречались самые разные проблемы — это и нестандартные HTTP-коды ответа (например, 999 или 666), ошибочные mime-типы (например, text/x-perl, video/x-ms-asf или image/jpeg), файлы в других текстовых форматах (RTF, MS Word, HTML, LateX, KOffice — всё текстовые форматы), неверная кодировка (UTF-16 или, например, совсем уж экзотическая для многих французская «nf_z_62-010»), ошибочный формат комментариев (С++-комментарии или HTML), иструкции роботу на натуральных языках, файлы в формате info.txt, ошибки синтаксиса (опечатки, изменение порядка, ошибочное использование расширений), открыто указываются места расположений секретных каталогов (phpmyadmin, админка, частные данные) и так далее.

Какие выводы? В свете последних дискуссий о том, должен ли поисковик индексировать сайт без явного согласия на то веб-мастера, замечает Andrew Wooster, поисковикам придётся иметь очень нетривиальный парсер robots.txt, отпределяющий кодировки и форматы, поддерживающий все расширения и исправляющий любые ошибки. И даже в этом случае, если сторонники подобного запрета победят, ¾ интернета, если судить по кодам ответа, будет просто недоступна поисковым системам (DMOZ — достаточно хорошая выборка, это не мусорные сайты).

Оставить комментарий

Фокусы с GIF, прозрачность и hover

Старинный револьвер с деревянной рукояткой и металлическим стволом на белом фоне.

Самые внимательные, наверное, заметили, что в прошлых заметках у меня на картинке использовалась эмуляция эффекта наведения на ссылку — посмотрите, если навести на картинку мышку, «ссылка», выделенная синим, на картинке подчеркнётся. И это не JavaScript.

Объяснение очень простое — картинка сделана с прозрачностью, далее при помощи CSS под неё подставлен белый фон, а при наведении (селектор «:hover») фон меняется на голубой. Такой же эффект использован на картинке с пистолетом слева (наведите мышку). Ссылка на картинке обязательна — без неё в Internet Explorer (версии ниже 7-й) фон менять не будет, «:hover» просто не сработает. Таблица стилей для этой картинки выглядит вот так:

a.gun:hover img { background: black } /* стиль при наведении мышкой */
a.gun img { margin: 0px; background: white } /* убираем поля в Opera и подкладываем белый фон */

HTML, соотвественно:

<a href="#" class="gun"><img src="gun.gif" /></a>

Если вам не ясно, почему пистолетик «стреляет» (т. е. почему изображение движется, когда наводишь мышку), то тут всё просто — прозрачная область движется (это animated GIF), на белом фоне этого не видно, когда фон меняется, создаётся эффект движущейся пули.

Ещё интересные эффекты можно получить, если использовать альфа-канал (полупрозрачность) в формате PNG, но, к сожалению, об анимации тут придётся забыть.

Оставить комментарий

Сайт на мобильных устройствах: Wall4PHP

Латвийский парень Kaspars Foigts реализовал библиотеку Wall4PHP. Это реализация WALL (Wireless Abstraction Library, оригинальная версия создана Luca Passani на Java) на языке PHP. Библиотека предназначена для поддержки сайтом мобильных устройств и позволяет на специальном языке описывать вёрстку, чтобы потом показывать сайт на том языке, который поддерживается устройством (XHTML, WML, модифицированный HTML для Imode-устройств).

Профиль устройства (что именно им поддерживается) описывается на специальном XML-языке WURFL, по этим профилям WALL определяет в каком виде устройству показать сайт. На странице автора есть англоязычное описание возможностей библиотеки, языка, а так же несколько примеров работы. Библиотека не развивается с конца 2006-го года (хотя на сайте есть TODO), но, похоже, достаточно стабильна и функциональна.

Оставить комментарий

Сайты в старых браузерах

Мы тут дискуссию развели в рабочем порядке — на тему того как должен показываться сайт в старых браузерах, в IE5, Opera7, FF1 и так далее. Мне подумалось, что надо подключать стили, который убирают всю разметку так, чтобы сайт показался обычной «колбасой», с навигацией. Осталось только отделить старый браузеры от новых. Пути, как мне видится, три — использовать CSS-хаки (но нужно подобрать их именно для этих версий), использовать JavaScript (просто подключать стиль в документ, проверяя версию через JavaScript) или проверять браузер на сервере (последний способ мне нравится меньше всего, так как возникают трудности с кешированием документов отдельно для двух типов браузеров).

Пока запишу себе в TODO попробовать сделать это у себя на блоге. На CSS-хаки надежды мало — они должны работать через ошибки в браузерах, а, в основном, они работают на том принципе, что каждая новая версия браузера поддерживает что-то новое, исключением из этого правила является IE, но там бо́льшая часть хаков относится к версиям ниже «семёрки».

Оставить комментарий

Layout в IE

На хабре есть крайне полезный, но малоизвестный материал «Изучаем наличие layout»:

Множество несоответствий (стандартам) Internet Explorer’а при визуализации веб-страниц может быть устранено путем присвоения конкретным элементам свойства layout. John Gallant и Holly Bergevin называют эти несоответствия «пространственными ошибками», подразумевая, что они часто могут быть исправлены, если задать элементу ширину или высоту. Это ведет к справедливому вопросу: каким образом layout может менять визуализацию одного элемента и совместное отображение нескольких?

Что такое layout в Internet Explorer, почему работает «хак» «height: 1%» и тому подобное — в этой статье. Крайне рекомендую к прочтению и пониманию всем, кто так или иначе занимается вёрсткой сайтов.

Оставить комментарий

Вертикальный текст: как?

Недавно возникла задача написания вертикального текста. Причём, именно текстом. В CSS3 есть свойство «writing-mode», но пока его никто, кроме Internet Explorer не поддерживает. Так что для остальных браузеров генерируется SVG с вертикальным текстом — изображение подключается при помощи протокола «data». Текст пишется дважды: для IE внутри div, для остальных браузеров (Safari, Mozilla/FireFox и Opera) — внутри атрибута тега «object». Дважды задаются и параметры текста (размер и имя шрифта).

<html>
<head>
    <style type="text/css">
        html>body .canv { display: none }
        .canv { filter: flipv() fliph(); writing-mode: tb-rl; width: 10px; height: 150px;
                font-size:12px; font-family: Arial; background-color: white }

        html>body .obj  { display: block; width: 10px; height: 150px }
        .obj { display: none }
    </style>
</head>

<body>
<div class="canv">Hello!</div>

<object class="obj" type="image/svg+xml"
    data="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'>
    <text x='-150' y='10' font-family='Arial' font-size='12' transform='rotate(-90)'>Hello!</text>
    </svg>">
</object>

</body>
</html>

Замечательно работает во всех соврененных браузерах, но есть недостатки: Safari до сих пор не умеет масштабировать SVG вместе с текстом (а SVG — это вектор!), а FireFox, масштабируя SVG, не увеличивает размеры object. Задание размеров в «pt» ситуацию не исправило.

Тег «object» задан фиксированных размеров, если нужно изменить размер, то параметры «x» и «y» у текста внутри SVG нужно будет исправить (процедура пересчёта значений очевидна, по-моему).

Конструкция «html>body» позволяет «прятать» CSS от Internet Explorer (включая седьмую версию), свойство background-color у класса «canv» проставлено для исправления ошибки отображения в Internet Explorer 6 и ниже — без этого свойства текст портится.

2 комментария

Detect SVG support

Искал код для проверки — поддерживает ли браузер SVG, так и не нашёл ничего подходящего. Написал свой, делюсь:

function DetectSVG()
{
    if (navigator.mimeTypes != null && navigator.mimeTypes.length > 0)
    return navigator.mimeTypes["image/svg-xml"] != null

    var svg = 0
    /*@cc_on
    @if (@_jscript_version>4)
        try { svg = 1; new ActiveXObject("Adobe.SVGCtl") }
        catch (e) { return 0 }
    @end
    @cc_off @*/

   return svg
}

Первая половина кода проверяет наличие SVG-плагина в браузерах Opera, FireFox и иже с ними, вторая — проверяет наличие SVG-плагинов (выпускаются фирмами Adobe и Corel) к Internet Explorer.

Оставить комментарий

Трюк с прозрачностью

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

Оставить комментарий

Эффекты для шрифта

Интересная техника изменения шрифта — наложить поверх текста полупрозрачную картинку, что даёт

ОЧЕНЬ ИНТЕРЕСНЫЕ ЭФФЕКТЫ.


Причём, такой текст индексируется поисковиками, его можно выделить и скопировать, а возможности его оформления почти безграничны и включают в себя даже анимацию, что может дать интересные эффекты, если применять эту возможность с умом.

Оставить комментарий

TYPE=RANGE

Оказывается, в HTML 3.0 должен был войти тег INPUT TYPE=RANGE, но его, по каким-то причинам, не включили в HTML 3.2, который стали поддерживать браузеры. Но тег поддерживается современными браузерами Opera и Safari, насколько я понимаю, как часть стандарта WebForms. FireFox даже последних версий (не говоря уже об IE) этот тег не понимает.

Оставить комментарий

Как узнать есть ли шрифт

Очень оригинальный JavaScript нашёлся на просторах интернета — JavaScript font detection, т. е. скрипт, который обнаруживает — есть ли у пользователя определённый шрифт или нет.

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

Если размеры совпадают, значит шрифта нет.

Оставить комментарий

MHTML

В предыдущей статье я описывал способ для Internet Explorer, позволяющий внедрить картинки в HTML-код. К сожалению, у него нашёлся недостаток — файл, в котором содержатся ресурсы, должен иметь расширение «mht». Иначе в некоторых версиях Windows браузер ничего не покажет.

Если подумать, это не сильно меняет дело — всего-то придётся выделить «упаковку» картинок в отдельный файл и подключать по мере необходимости. Например, так:

<img src="mhtml:http://sample.com/package1.mht!image.jpg" />
<img src="mhtml:http://sample.com/package1.mht!another_image.gif" />

и так далее. Основное достоинство способа — объединение нескольких картинок в одном соединении и его удаётся сохранить.

Сегодня я расскажу как добиться мультибраузерности при помощи SSI. В других скриптовых языках такой проблемы, понятно, не возникает. Я буду рассматривать SSI веб-сервера Apache, для других серверов, думаю, адаптировать код можно будет без особых проблем. Странно, SSI, этот простой и быстрый язык, который часто отлично подходит для организации нагруженных сайтов, где хотелось бы держать информацию структурированно, почему-то считают недостаточным для программирования. Тем не менее, на нём можно делать достаточно сложные вещи (я как-то писал «песню про пиво» на этом языке, загляните в раздел «99»).

Символом «собачки» (@) я буду выделять места, где перевод строки не нужно ставить — просто мне приходится разбивать длинные места на части. Описание, если не интересно, можно и не читать, просто скопировать всё в нужный файл и положить в каталог /images/.

В настройках Apache или .htaccess должна быть включена обработка SSI в файлах .html и .mht:

AddHandler server-parsed .html .mht

Первый файл (или файлы), который понадобится — это файл самой картинки. Он должен начинаться с полного имени картинки, плюс расширение .html. Например, «1.jpg.html», внутри нужно указать MIME-тип картинки в переменной «TYPE» и после include пометить код картинки в base64:

<!--#set var="NAME" value="$QUERY_STRING" -->@
<!--#set var="TYPE" value="image/jpeg" -->@
<!--#include virtual="pict.html" -->@
4AAQSkZJRgABAgAAZABkAAD...код картинки...mJiBFoxCGkShUxyGCMYMRcSwwRiMdRZ

Следующий файл — img.html. В нём проверяется из какого браузера его вызывают — Internet Explorer или всех остальных (вторым условием убирается Opera, которая иногда притворяется IE) и, в зависимости от этого, выводит, либо ссылку на mht-файл (у меня в коде считается, что все эти файлы лежат в каталоге /images), либо data URL, который генерирует pict.html:

<!--#if expr="$HTTP_USER_AGENT=/MSIE/ && $HTTP_USER_AGENT!=/Opera/" -->@
mhtml:http://<!--#echo var="HTTP_HOST" -->/images/package1.mht!<!--#echo var="QUERY_STRING" -->@
<!--#else -->@
<!--#include virtual="$QUERY_STRING.html?$QUERY_STRING" -->@
<!--#endif -->

Внутри файла package1.mht ссылки на файлы картинок (обратите внимание на параметры вызова в include virtual), в константе BOUND задаётся boundary (разделительная строка), о которой я говорил в прошлый раз. В include надо перечислить (пример показан для двух файлов) все файлы картинок, которые будут входить в этот набор.

<!--#set var="BOUND" value="Next_Section" --><!--
MIME-Version: 1.0
Content-Type: multipart/related; boundary="<!--#echo var="BOUND" -->"

--<!--#echo var="BOUND" -->
Content-Location: index.htm
Content-Transfer-Encoding: base64
Content-Type: text/html

<!--#set var="MHT" value="1" -->
<!--#include virtual="1.jpg.html?1.jpg" -->
<!--#include virtual="2.jpg.html?2.jpg" -->

--<!--#echo var="BOUND" -->-->

Последний файл — pict.html. Вызывается он из файлов картинок. Если он вызывается из mht, то выдаёт кусок mht-кода для данной картинки, иначе — data URI.

<!--#if expr="$MHT" -->--<!--#echo var="BOUND" -->
Content-Location: <!--#echo var="NAME" -->
Content-Transfer-Encoding: base64
Content-Type: <!--#echo var="TYPE" -->

<!--#else -->data://<!--#echo var="TYPE" -->;base64,<!--#endif -->

Теперь, как применять эту груду файлов. Всё очень просто — просто вставляем в нужно место следующий тег:

<img src="<!--#include virtual="/images/img.html?2.jpg" -->" />

И смотрим на результат. В исходном коде в IE мы должны увидеть ссылку на package1.mht, в остальных браузерах — data URI, во всех браузерах — картинку.

Оставить комментарий

Колдуем с MHTML

Позже, после того, как я уже написал эту статью, мне прислали необходимое уточнение. Я провёл несколько экспериментов, попросил своих друзей и знакомых опросить своих друзей и знакомых и вот что выяснилось:

В некоторых версиях Windows XP, 2000 (закономерность не выявлена, но, видимо, дело в наличии каких-то Service Pack) и, кажется, во всех 2003, способ не работает, если расширение файла не mht. Это несколько сужает сферу применения данного способа.

Обход этой проблемы читайте в следующей статье. Далее сама статья:

Сегодня немного поколдуем, ок? Тем, кому не интересна кухня, где готовят внутренности сайтов, могут перейти к просмотру чего-то более интересного, остальные оставайтесь.

Браузеры всё больше превращаются в комбайны, которые поддерживают десятки схем доступа к данным, от всем известных file, ftp, http, https, до полузабытых gopher, finger, news и так далее. Среди этого списка есть интересная схема — data, который поддерживают уже, кажется, все браузеры, кроме Internet Explorer (включая беты седьмых версий). Для тех, кто незнаком с ним, общий вид строки запроса в этой схеме выглядит так:

data://[mime-тип;][тип кодирования],данные…

смысл в том, что данные (картинки, javascript, другие ресурсы) можно помещать внутрь HTML. Эта схема является частью стандарта HTML 4.0, если я не ошибаюсь, но, в силу того, что она не поддерживается основным игроком на рынке браузеров, используется лишь эпизодически — чаще всего в интранет-приложениях и расширениях к Opera и Mozilla FireFox. Выглядит это, примерно, так:

<img src="data:image/png;base64,iVBORw0KGgoAAAAN...и так далее">

Эта схема, кроме возможности помещать различные данные в HTML, имеет и более очевидные преимущества. Обычно, браузер открывает не более 2-4 соединений с сервером, через которые и получает данные. Если на странице очень много мелких картинок, браузер не имеет возможности загрузить и показать их одновременно — приходится ограничиваться означенным количеством соединений.

Мы, в нашей студии, обычно стараемся использовать карту ссылок, вместо нескольких мелких кнопок, например, для ускорения загрузки. Я очень много разговаривал с поисковиками Google и Yandex, но они уверены, что в IE внедрение ресурсов в HTML невозможно. Так ли это?

Нет. По крайней мере мне удалось найти минимум один способ сделать это. В интернете я ничего подобного не встретил, так что будет считать, что его изобрёл я. Натолкнула меня на эту мысль одна из кошмарных домашних страниц, которую сверстали в Microsoft Word и сохранили… в формате MHTML.

Этот формат первым начали использовать в браузере от Microsoft (поэтому его иногда расшифровывают как «Microsoft HTML») для того, чтобы можно было сохранять текст со всем содержимым — стилями, изображениями в одном файле, поэтому этот формат ещё называют веб-архивом (Web Archive). Чаще же всего его название расшифровывают как MIME HTML и в этом заключается главная проблема.

MIME HTML сильно отличается от обычного HTML форматом — внутри заголовок, информация об именах и форматах файлов, кодированные файлы изображений и так далее — более всего это похоже на файлы писем с вложениями (посмотрите исходный текст письма в своём почтовом клиенте). Нам было бы интересней, если бы в остальных браузерах показывалось бы что-то более похожее на HTML.

Просматривая веб-архив в браузере, я обнаружил, что IE отображает файлы архива через специальную схему — mhtml. У него есть интересная особенность — он позволяет адресовать файлы внутри веб-архива извне, вот так:

mhtml:http://example.com/file.mht!image.jpg

Причём, оказывается, браузер довольно вольно подходит к формату файла, лишь бы внутри были необходимые секции, что позволяет легко заключить архив внутрь HTML-комментария:

<!--
Content-Type: multipart/related; boundary="=_NextPart_01C6A9B1.539AB070"

--=_NextPart_01C6A9B1.539AB070
Content-Location: index.htm
Content-Transfer-Encoding: base64
Content-Type: text/html

--=_NextPart_01C6A9B1.539AB070
Content-Location: img.jpg
Content-Transfer-Encoding: base64
Content-Type: image/jpeg

4AAQSkZJRgA....закодированная...base64...картинка...BAgAAZABkAADMdRZ

--=_NextPart_01C6A9B1.539AB070-->

<body>
<img src="mhtml:http://www.test/index.html!img.jpg">
</body>

Те, кто знает как устроено обычное электронное письмо изнутри, разберутся и сами, для остальных расскажу. Строка, которую вы видите после слова «boundary», разделяет файл на секции. Секции начинаются с двух минусов и разделяющей строки. Заканчивается веб-архив разделяющей строкой, которая начинается и заканчивается двумя минусами — у меня завершающие минусы являются частью закрывающей части HTML-коментария. У секций есть заголовок:

Content-Location — имя файла внутри архива;
Content-Tranfer-Encoding — формат кодирования файла, экономичнее всего использовать base64;
Content-Type — MIME-тип файла;

если вы не знаете, что такое base64 и MIME-тип, то лучше обратиться к поисковику — такие вещи лучше знать. Первая секция с типом «text/html» — обязательная, без неё Internet Explorer не отобразит ваши файлы, остальные могут содержать данные любых типов. Ссылка может указывать на тот же самый или любой другой файл, который содержит веб-архив.

Я не уверен насчёт четвёртой версии браузера, но 5.0 и выше должны отобразить такой HTML нормально. У этого способа есть преимущество перед схемой data — на файл можно ссылаться несколько раз. Организация вывода разного контента для двух групп браузеров — сейчас довольно простая задача. Лучше всего, конечно, использовать для этого язык на стороне сервера (для JavaScript объёмы данных слишком значительные) — например, SSI или PHP.

Кстати, Opera 9 так же поддерживает веб-архивы, но использует для этой цели другую схему — «attachment». Но Opera 9 слишком мало распространена и, кроме того, этот браузер давно поддерживает схему «data».

Ещё хотелось бы упомянуть, что Internet Explorer поддерживает ещё одну схему, через которую, вероятно, можно получить доступ к ресурсам веб-архива — «mid», но я в этом не уверен и никаких экспериментов по этому поводу не проводил.

5 комментариев

← 1 60 61 62 63 64 67 →