Пишу, по большей части, про историю, свою жизнь и немного про программирование.

Колдуем с 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 комментариев
Василий Стрельников 2019

... и все/таки..?!? Каким способом?!...,образом..,действием...,бездействием....открыть файл MHTML в браузере Хром для планшета андроид 4/4.....?!?
с ув.дед Василий...инв.2гр...г.2019...апрелю 20...от Р.Х..

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

Что?

Василий Стрельников 2019

.... усе то/жеть....! Наша крестьянска телега и пононе туточьки...
Уважаемый господин,товаришчь,продвинутый цифробарин....! Оченно буду признателен,ежели обьясните...просто...,на пальцах однех рученок......,КАК....,просто КАК открыть на планшете системы андроид 4/4 артели САМСУНГ....,открыть,прочесть,просмотреть сообщение с вложением....?!?! Вложение загружаетси....,но....,НО.....далее бандура пишеть,что нет приложения,чтобы открыть енто вложение....?!?!
Возможно проживу покеда ишо немного и без оного послания...,но мятежно-любознательна натура червячит душонку простого Рассейского крестьянина....!!!
Нижайше прошу без наворотов,задурений,умняка....! Т.К. усложнять завсегда усем просто.....,а вот упрощять не многие сподобились при жизни.......
с ув.дед Василий...инв.2гр...мутант ядерного полигону СССР....Алт.край.....г.2019...апрелю 20...от Р.Х..

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

Вы можете по-русски писать? Ничего непонятно.

Василий Стрельников 2019

... все ясно Уважаемый...! Слаб человек...,любит показать свою значимость,пупырчатость....! Уверяю,что всегда есть другие варианты,способы ,как открыть файлу MHTML минуя особо «Одаренных»....!
...без ув.дед Василий...крестьянин Алт.кр...г.2019..апрелю 20...от Р.Х..

P.S.. — сожалею...,но птичьим языком не владею...,а так/бы почирикали.....!!!