Эмуляция data:URL для IE6-7 — используем MHTML-включение

Автор: Александр Головко и Егор Скорняков Дата публикации: 24.01.2011

С помощью схемы data:URL можно встраивать изображения в веб-страницу, и, тем самым, заставить сайт работать быстрее. Подробнее этот вопрос рассмотрен в статье Встраиваем изображения — data:URL.

К сожалению, в браузерах IE6-7 в чистом виде такой прием не пройдет. То есть, если ты используешь внедрение картинок, для Ослоподобных нужны будут специальные костыли.

Задача

Предположим, есть картинка (img) внутри контейнера. Для контейнера задан какой-то фон. Обе картинки внедрены с помощью схемы data:URL.

<div class="container">
	<img src="data:image/png;base64,BASE64 CODE" width="100px" height="100px" alt=""/>
</div>
.container {
	position: relative;
	width: 110px;
	height: 110px;
}
.container img {
	position:absolute;
	top: 5px;
	left: 5px;
	background-image:url(data:image/png;base64,BASE64 CODE) no-repeat;
}

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

По сути, имеем две немного разные задачи — поддержка IE6-7 внедрения картинки в HTML (тег img) и в CSS (свойство background).

Что делать с HTML

Вообще говоря, в статье Встраиваем изображения — data:URL делается вывод, что использовать эту технологию для HTML не очень рационально. Если ты все-таки хочешь использовать встраивание в HTML, придется тебя немного огорчить. Для IE6-7 сделать более-менее приличные костыли не получится. В качестве варианта, можно предложить подставлять для упрямых браузеров обычную картинку из внешнего файла:

<div class="container">
	<img src="data:image/png;base64,BASE64 CODE" width="100px" height="100px" alt=""/>
	<!--[if lte IE7]><img src="img/pic.png" width="100px" height="100px" alt=""/><![endif]-->
</div>

Этот трюк возможен благодаря тому, что картинку мы разместили абсолютным позиционированием (см. CSS выше). Второй img просто ляжет поверх первого. Конечно, не очень красиво, но действенно. А вообще, повторюсь, схему data:URL не стоит использовать для включения картинки в HTML, по крайней мере, пока.

Внедряем в CSS

Тут ситуация гораздо лучше. Вместо data:URL можно использовать MHTML-включения.

Выглядит это дело примерно так (для примера тут, как бы, описаны две png картинки):

/*
Content-Type: multipart/related; boundary="_"

--_
Content-Location:1
Content-Type: image/png
Content-Transfer-Encoding:base64

BASE64 CODE

--_
Content-Location:2
Content-Type: image/png
Content-Transfer-Encoding:base64

BASE64 CODE

--_--
*/

где

  • Content-Location:1 — цифра является идентификатором картинки. По этому номеру мы будем к ней обращаться в конкретном CSS-правиле. Нумеруем сами;
  • Content-Type: image/png — MIME-тип встраиваемых данных;
  • Content-Transfer-Encoding:base64 — тип кодировки;
  • BASE64 CODE — собственно код картинки (огромный блок данных).

Чтобы обратиться к картинке в CSS, указываем полный URL файла с mhtml-включением (в данном случае, сам CSS), и, после символа «!», номер картинки (Content-Location). Например:

.container {
	background-image:url(mhtml:http://www.xiper.net/css/ie.css!1);
}

Демо-пример странички с data:URL для фоновых картинок (CSS) и для тега img (HTML).

Проверено в:

  • IE 6-8
  • Firefox 3
  • Opera 9.5-10
  • Safari 4
  • Chrome 8

MHTML и Vista

Достаточно чувствительный удар по описанному способу внезапно прилетел от Microsoft. Как оказалось, Vista IE7 при кэшировании MHTML файла отказывается показывать изображения. Если сделать файл некэшируемым, то все работает нормально, но в случае с кэшированием картинок в Vista IE7 мы не увидим.

Но, не пугайся, если встретишь упоминание об этой проблеме. Ее уже решили. Например, обновленная версия сервиса duris составит корректный (в том числе и с точки зрения Vista IE7) MHTML.

Вывод

Имеем рабочий вариант внедрения картинок в CSS во всех основных браузерах. С внедрением в HTML по-прежнему советую не торопится.

Материалы: