Евгений Степанищев

Я — эксперт в области разработки веб-приложений и безопасности в интернете. Каждый месяц мой блог посещают около 90 тысяч человек. Работаю техническим директором в «Системах документооборота», занимаюсь электронным правительством.

data URL в IE

Пару лет назад я занимался проблемой data URL в Internet Explorer, добился определённых результатов, но то, что получилось, использовать было невозможно. Data URL (иногда его ещё называют «протокол data:») — возможность вставлять ресурсы (графику, CSS, JavaScript и так далее) в HTML код.

Выглядит это примерно так:
<img
src="data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAw
AAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFz
ByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSp
a/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJl
ZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uis
F81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PH
hhx4dbgYKAAA7" />
В Data URL указывает тип содержимого и способ его кодирования. Способа кодирования два — base64 (именно он и указан в примере), увеличивающий содержимое на треть и URL encoding (в этом случае способ кодирования не указывается) — привычный многим способ кодирования при помощи %xx, в лучшем случае вообще не увеличивает размер содержимого, в худшем — увеличивает в три раза.

Кстати, в настоящее время IE8b1 поддерживает data URL, но, увы, длиной не более 32Кб.

Теперь амбула.

Вчера ночью мне пришла в голову идея как можно попытаться корректно совместить data URL и включение картинок через протокол mhtml. То, что у меня не получилось два года назад, получилось сейчас.

Результат — готовый код на PHP из двух функций. Первую функцию («bolk_data_uri_header») нужно вызвать в самом начале перед выводом любого вашего кода, вторую («bolk_data_uri») собственно для включения картинки в код. Надеюсь на примерах всё понятно:
bolk_data_uri_header();

bolk_data_uri('myjpeg.jpg');
bolk_data_uri('ourpng.png', 'border: 2px dotted red');
Код самой библиотеки:
function bolk_data_uri_header()
{
	echo "<!--\n"
		."Content-Type: multipart/related; boundary=\"=_NextPart_01C6A9B1.539AB070\"\n\n"
		."--=_NextPart_01C6A9B1.539AB070\n"
		."Content-Transfer-Encoding: base64\n"
		."Content-Type: text/html\n"
		."-->\n\n";

}

function bolk_data_uri($file, $style = '')
{
	if (!( file_exists($file) && ($data = @getimagesize($file)) )) return false;

	$name = uniqid('', true);

	if ($style <> '') $style = ' style="'.htmlspecialchars($style).'"';

	echo "<!--\n"
		."--=_NextPart_01C6A9B1.539AB070\n"
		."Content-Location: {$name}\n"
		."Content-Transfer-Encoding: base64\n"
		."Content-Type: {$data['mime']}; -->\n"
		."<object data='data:{$data['mime']};base64,\n\n";

	echo base64_encode(file_get_contents($file));

	echo "' {$data[3]}{$style} type='\n{$data['mime']}'><img "
		."src='mhtml:http://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}!{$name}' {$data[3]}{$style} /></object>\n\n"
		."<!--\n"
		."--=_NextPart_01C6A9B1.539AB070-->";

	return true;
}
У данного метода, по сравнению с обычными data URL есть масса ограничений: необходим специальный заголовок в начале файла, т.е. этот метод невозможно использовать на чужих сайтах, этим методом нельзя воспользоваться (по крайней мере не в таком виде) для включения ресурсов внутрь CSS или JavaScript. В принципе, тут есть достаточно большое поле для экспериментов, возможно все или некоторые из проблем можно решить.

В разделе «храню» есть пример, который можно потестировать на имеющихся у вас браузерах. Уже протестировано на Opera 9.25 и 9.50b, FF 2.0.0.13 и 4 (Minefield), Safari 3.1 (Safari под iPhone — тоже), Internet Explorer 6.0SP2 и 7.0, Sony PSP browser, Opera mini, Netscape Navigator 9.0.0.5.
3 апреля 2008 19:39

Sam Dark (Sam.Dark.myopenid.com)
3 апреля 2008, 21:32

Проверено в Opera 9.25, IE7, FF4(Minefield).

bolk (bolknote.ru)
3 апреля 2008, 22:47, ответ предназначен sam.dark.myopenid.com:

Спасибо, занесу!

xplay (openid.yandex.ru/users/xplay)
4 апреля 2008, 09:05

Супер. Ура первооткрывателю =)

bolk (bolknote.ru)
4 апреля 2008, 14:48

:)

Sas (mmasco.myopenid.com)
5 апреля 2008, 01:56

IE6 SP1 - не работает.

blog.ad.by (blog.ad.by)
5 апреля 2008, 11:17, ответ предназначен bolk (bolknote.ru):

Я погонял на всем что входит в MultipleIEs: 4.01, 5.01, 5.55, 6.0. Работает везде, только мой опыт говорит что верить этому нужно с осторожностью: например, VML в нормальном 5.01 работает, а в этом комплекте на 5.01 - нет.

bolk (bolknote.ru)
5 апреля 2008, 11:31, ответ предназначен Sas (mmasco.myopenid.com):

Полная версия подопытного? У меня работает (только что посмотрел) на IE6.0.2900.2180.xpsp_sp2_rtm.040803-2158.

bolk (bolknote.ru)
5 апреля 2008, 11:32, ответ предназначен blog.ad.by:

Спасибо, но, да на MultipleIE данные могут отличаться.

u1itka.livejournal.com (u1itka.livejournal.com)
6 апреля 2008, 22:32

А что там должно быть? Если пиктограмма "лист бумаги", то на Safari в iPhone тест пройден.

bolk (bolknote.ru)
7 апреля 2008, 12:20, ответ предназначен u1itka.livejournal.com:

Она и должна быть, спасибо.

Sas (mmasco.myopenid.com)
11 апреля 2008, 07:36, ответ предназначен bolk (bolknote.ru):

Version:6.0 2800.1106 Update version: SP1

bolk (bolknote.ru)
11 апреля 2008, 13:06, ответ предназначен Sas (mmasco.myopenid.com):

Дико забавно. А что выдаёт? Крестик? mht нормально показывает?

Sas (mmasco.myopenid.com)
14 апреля 2008, 02:37

Точку в квадратике выдает :)
http://calc.ugh.ru/mhtml.gif

bolk (bolknote.ru)
14 апреля 2008, 11:43, ответ предназначен Sas (mmasco.myopenid.com):

А! Это должно быть тег OBJECT, а можно вас по аське помучать? Я думаю можно попробовать в conditional comments всё это сунуть.

ICQ# 2-99-3333

arikon.livejournal.com (arikon.livejournal.com)
14 сентября 2008, 19:28

Женя, в FF 3.0.1 под Mac OS X работает, а в Safari 3.1.2 (5525.20.1) - не работает, показывает только квадратик без иконки.

bolk (bolknote.ru)
14 сентября 2008, 20:31, ответ предназначен arikon.livejournal.com:

А этот?
http://bolknote.ru/files/ie-data-url-2.php

arikon.livejournal.com (arikon.livejournal.com)
15 сентября 2008, 12:10, ответ предназначен bolk (bolknote.ru):

А этот работает. И в Windows тоже (первое решение в Safari под Windows тоже не работало).

Опубликуй исходник нового решения.

bolk (bolknote.ru)
15 сентября 2008, 14:24, ответ предназначен arikon.livejournal.com:

«Новый» исходник ровно такой же как и старый, просто отделение IE сделано через conditional comments.

molder.moikrug.ru (molder.moikrug.ru)
16 декабря 2008, 04:20, ответ предназначен bolk (bolknote.ru):

вот оно, счастье!

id.rambler.ru/users/danyv/ (id.rambler.ru/users/danyv/)
17 мая 2009, 12:05

При использовании данного решения с протоколе https в IE есть проблема с security warning: http://iescripts.org/view-scripts-464p1.htm (не важно как реализовано: как в примере через JavaScript или через mhtml). Может быть кто-то встречался и решил эту проблему?

bolk (bolknote.ru)
18 мая 2009, 01:16, ответ предназначен id.rambler.ru/users/danyv/:

mhtml:https не спасает?

rakeev.livejournal.com (rakeev.livejournal.com)
2 ноября 2009, 09:42

В Firefox тоже появляется "соединение частично зашифровано"
Обидно, из-за этого придется от data:uri отказаться :(

bolk (bolknote.ru)
2 ноября 2009, 11:34, ответ предназначен rakeev.livejournal.com:

Правда? Вот это уже удивительно. А какая версия FF?

sillysunnybear.livejournal.com (sillysunnybear.livejournal.com)
13 декабря 2009, 14:49

Эту ошибку в Fx вроде исправили (почти год мучили)

bolk (bolknote.ru)
13 декабря 2009, 19:06, ответ предназначен sillysunnybear.livejournal.com:

Пытаешься говорить как положено? «Fx»? :)

А в какой версии исправлено?

Павел (инкогнито)
9 ноября 2010, 05:22

тут http://www.websiteoptimization.com/speed/tweak/inline-images/folder-testcss.html и тут http://bolknote.ru/files/ie-data-url.php у меня в ie 8.0.7600.16385 картинки data url не показываются! Тестил в 32х и 64х битном 8ие, windows 7 лицензионный, постоянно обновляется.

bolk (bolknote.ru)
9 ноября 2010, 13:02, ответ предназначен Павлу

Посмотрите вот тут: http://bolknote.ru/files/ie-data-url-2.php

Давал же ссылку уже в комментариях.

http://search-bot.net (инкогнито)
15 октября 2011, 19:54

Не работает в ИЕ. Vista Sp2

bolk (bolknote.ru)
15 октября 2011, 22:25, ответ предназначен http://search-bot.net

«Микрософт» прикрыла лавочку: http://www.google.ru/search?client=opera&rls=ru&q=microsoft+mhtml+information+disclosure+vulnerability&sourceid=opera&ie=utf-8&oe=utf-8&channel=suggest

Ваше имя или адрес блога (можно OpenID):

Текст вашего комментария, не HTML:

Кому бы вы хотели ответить (или кликните на его аватару)

Подсказка по написанию комментария

В комментариях можно применять следующую специальную разметку:

  • слово, обрамлённое в «звёздочки» выделяется *жирным*
  • ссылка становится ссылкой: http://bolknote.ru
  • ссылка в скобках также становится ссылкой, закрывающая скобка не захватывается: (http://bolknote.ru)
  • каждую строку цитаты следует начинать со знака «больше»:
    > это цитата
    > из двух строк
  • можно вставить картинку, залитую на один из сервисов: «Яндекс.Фотки», «Фликр» или «Пикплз». Для этого нужно вставить на страницу полный адрес вашей картинки на сервисе, он превратится в картинку:

    http://fotki.yandex.ru/users/bolknote/view/274311?page=3