data URI

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


    Подробнее о data URL можно узнать из свежей статьи на «Хабре» «Картинки в теле страницы с помощью data:URL». Хотелось только её дополнить двумя замечаниями: IE8b1 поддерживает data URL длиной не более 32Кб, в современных версиях других браузеров ограничений увидеть не удалось, Safari/Opera/FF показали изображения размером около 700Кб.


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


    Вчера ночью мне пришла в голову идея как можно попытаться корректно совместить 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).'"'; 
        $mime = strpos($_SERVER['HTTP_USER_AGENT'], 'Gecko') ? " type='{$data['mime']}" : '';
    
        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}{$mime}'><img " 
            ."src='mhtml:http://{$_SERVER['HTTP_HOST']}"
            ."{$_SERVER['REQUEST_URI']}!{$name}' {$data[3]}{$style} /></object>\n\n" 
            ."<!--\n" 
            ."--=_NextPart_01C6A9B1.539AB070-->"; 
    
        return true; 
    }
    



    Секрет в совмещении данных, чтобы IE, обратившись к странице по протоколу mhtml нашёл нужный кусор, «спрятанный» внутри тега, а остальные браузеры увидели бы картинку через data URL.


    Код тестировался под Opera 9.50b, FF 2.0.0.13, Safari 3.1 и IE6. Предложения и результаты испытаний — прошу в комментарии.


    Оригинал записи опубликован в моём блоге.
    Share post

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 85

    • UFO just landed and posted this here
      0
      НА SONY PSP работает!!!
        +1
        Отлично :)
        0
        Извините, но я как Девушка не всегда сведущая, но это фантастика. Дайте кармы человеку- такого никогда еще не видела!!!

        Вопрос автору - а Вы где либо видели что либо подобное, просто тут для капчей мега помощь!!! Завтра же разрабам своим в туду! Спасибо большое.
          +1
          Нигде ничего подобного не видел. Над вопросом работал полностью самостоятельно.
          • UFO just landed and posted this here
              0
              Боюсь, я не смогу перевести адекватно, может попрошу кого-то :)
                0
                Спасибо что дали:) Хочу картинку размером 30 кб - если такое для flash сделать ... то это революция.
                  0
                  Думаю, внедрит flash так тоже удасться. Только чуть доделать код (теги для Flash другие будут).
                    +1
                    Столько грамматических ошибок наделал. Прошу у всех прощения — спешу на поезд.
              0
              Вставьте хабракат перед началом кода, пожалуйста.
                0
                Извините, не мог, был в другом городе, сейчас не актуально, наверное уже.
                0
                В Firefox 2.0.0.13 - не работает на файле размером 35594 байта. Указанный в статье пример с маленькой картинкой - работает.
                  0
                  Очень странно, у меня открываются куда более значительные файлы. Какая OS?
                    0
                    Winodws XP Prof. Вроде бы все правильно сделал.
                  –1
                  Сия фигня увеличит суммарный html-код страницы, соответственно процент значащих слов в коде страницы уменьшится. Значит, поисковики будут "худшего мнения" о таких страницах, значит это анти-сео какое-то :)
                  Не покатит.
                    0
                    Что мешает вынести во внешний CSS?
                      0
                      тогда количество http-запросов не уменьшится, и вообще тогда неясно, зачем оно вообще нужно
                        0
                        А какая разница-то, что в коде фунции будут выполнятся, что в CSS? Во втором случае как раз таки запросов будет меньше, потому как CSS имет свойство кэшироваться.
                          0
                          графика, CSS, JavaScript и так далее - всё это тоже умеет кэшироваться, так как выносится во внешние файлы обычно.
                        • UFO just landed and posted this here
                            0
                            Ну, так конечно можно, но есть еще проблемы:
                            1. base64-код в среднем на 33% больше, чем исходный код, т.е. подключаемый файл будет еще больше, чем большой.
                            2. Все места, где выводятся картинки, надо будет делать слоями с бэкграундом.

                            Кроме того, я вообще не очень понимаю, кому особенно мешают http-запросы. И зачем пользователю грузить бОльший объем данных, чем надо - тоже не ясно.
                            • UFO just landed and posted this here
                                0
                                по http-запросам - очень хорошо избегать их для служебных изображений и прочих маленьких и нужных "штучек" путём выставления Expires/max-age на год - не будет даже conditional GET-запросов.
                                Плюс, как я уже говорил, в IE8b1 уже 6 одновременных соединений на домен, думаю, остальные производители браузеров тоже быстро увеличат это количество.
                                Мне почему-то кажется, что единственное применение dataURI - как раз для таких "нестандартных" случаев, как капча.
                                  0
                                  http://www.kuzpress.ru/data_url.html
                                    0
                                    Результат очень хороший, жаль два отдельных файла нужно :)
                                  0
                                  "Правда, в конкретно описанном здесь кроссбраузерном методе, пожалуй, вынести в CSS как раз и не получится."
                                  у меня вроде получилось
                          +3
                          Тот, кто будет затачивать сайт под seo, вряд ли станет использовать такую реализацию. Ее не нужно и не следует использовать где попало и как попало вообще.

                          P.S. Главное увеличить процент фраз «заработать на блоге» и «развратные учительницы сосут прямо на перемене»…
                            0
                            Поисковики внутрь тегов (исключение — разве что атрибуты alt и title) не заглядывают. Не болтайте ерундой.
                              0
                              Одна табличная вёрстка хуже вёрстки на div'ах прежде всего тем, что у нее худший процент полезного контента в теле страницы. Хотя поисковики в тэги и не думают заглядывать.
                                0
                                Это как-то противоречит тому, что я сказал?
                                  0
                                  Да.
                                  Код
                                  [span class="asdfsadfadsf" id="sadfkjhdsaghjklklghjklafh"]Текст[/span]
                                  хуже для поисковиков, чем
                                  [span]Текст[/span]
                                  в связи с тем, что поисковики считают суммарный размер страницы, и уже относительно его высчитывают процент вхождения нужного слова.
                                    0
                                    Дайте ссылку, подкрепляющую ваши слова.
                            0
                            Симпатичный у вас сайт.
                              0
                              Спасибо!
                              0
                              Зачем такой изврат? Вот честно, не понимаю. Мало того, что base64 сам по себе больше чем изображение, дак вы еще к нему какую-то фигню добавляете. Что нам это дает? Уменьшение числа http-запросов? Ну дак вынесите картинки на отдельный домен, делов-то.
                                0
                                Уменьшение числа запросов здесь скорее не для уменьшения нагрузки на сервер, а для ускорения загрузки страницы. см. выше комментарии про аякс, который стоит пока грузятся картинки.

                                ну и + принудительный показ CAPTCHA (см. мой комментарий строчкой ниже)
                                  0
                                  Где я сказал, что это для уменьшения нагрузки на сервер? Какой нафиг яакс? Вы вообще про что? Кто стоит, куда стоит... бр, может стоит сперва хоть немного почитать теорию? Разнос картинок на другие домены/поддомены как раз и делается для того, чтобы как можно больше запросов совершались одновременно. Браузер ограничевает количество запросов к одному домену.
                                  А в опере эта ваша копча не показывается.
                                  Велосипед на квадратных колёсах изобретаете.
                                    0
                                    Во-первых, я ничего не изобретаю. Ну и ок, вы правы, вынос картинок на отдельный домен тоже хороший способ, я не знал про эту особенность работы браузеров.

                                    Остаются ситуация, когда заголовки http и картинка весят существенно больше чем base64 и случай с узким каналом, когда всё выглядит некрасиво из-за недогрузившихся мелких графических элементов (аякс тут тоже тормозит - канал-то занят).
                                      0
                                      Иэх... мелкие картинки в одну побольше и играть позиционирование бакграунда.
                                      Ну а если это лень, то элементарно спасет обычный dataURL (до 32 кб везде) и не надо никакие там mhtml'ины приплетать.
                                      Keep it simple =)
                                        0
                                        Позиционирование бэкграунда - примерно того-же уровня изврат, что и data:, как мне кажется. (-:

                                        Ну я, разумеется, надеюсь что все сознательные люди будут использовать простейший из доступных вариантов. Влазит в 32К - хорошо, не влазит - способ bolk'а.

                                        Это лучше чем вообще не иметь выбора, осгласитесь.
                                          0
                                          Теорию читайте, в общем.
                                            0
                                            есть ещё что-то из этой области кроме особенностей расхода соединений браузером, что мне следует прочитать?
                                              0
                                              Дак полно материала по ускорению загрузки страниц =)
                                              Прочитайте гайды от yahoo. Почитайте хабр =)
                                            0
                                            там как раз нету никакого изврата, мелкие элементы можно грузить с 1 картинки, только позиционировать их как надо. А эта обработка в php + код больше - ускорится ли загрузка? и надо ли оно такое вообще...
                                              0
                                              Позиционирование бэкграунда 4 постами выше это и есть с 1 картинки. А вообще это называется CSS-спрайты.
                                            0
                                            я вот тоже не могу придумать, зачем может понадобиться отдавать через dataURI картинки, бОльшие, чем те же 32 кбайта. Это и какая-никакая, но нагрузка на CPU, это уменьшение распараллеливания скачивания (в том же IE8b1 можно качать в 6 одновременных соединений с одного домена), да и плюс к тому сама хтмлка становится больше. Не понимаю.
                                      0
                                      Почитайте статью о data URL, ссылку на которую я дал в статье.
                                        0
                                        Эх, еще один... да ладно, ладно, стройте велосипеды с квадратными колёсами, мне не жалко. Технологию надо не только знать и понимать, но еще четко осозновать её применение.
                                          0
                                          Вот и прочитайте внимательно обо всех плюсах. Вы обсуждаете только один. Кроме того, «вынесите картинки в отдельных домен» для многих не вариант.
                                            0
                                            Хорошо, распишите плюсы вашего слияния dataUrl и mhtml. Только сперва про минусы прочитайте.
                                              0
                                              Я эту тему достаточно изучил ещё 2 года назад. Плюсы описаны в статье, на которую я дал ссылку.
                                                0
                                                Пофиг, просто знайте, что на дворе 2008 год и знания приобретенные 2 года назад утратили свою ценность.
                                                  0
                                                  Вы ошибаетесь. Читайте статью.
                                                    0
                                                    Ну дак будут примеры то, нет? В статье 3 плюса (все они легко реализуются и обычными изображениями) и 5 минусов. А ваш способ добавляет минусов только.
                                                      0
                                                      Я не понимаю.

                                                      Я уже 3 или 4 раза попросил вас прочитать статью. Не желаете вникать в материал — досвидания.
                                                        0
                                                        Эх, вам не статьи писать надо, а общаться учится, хотя бы. Забейте и дальше радуйте нас велосипедами!
                                                          0
                                                          Вы, похоже, не подозреваете кто я. Удивительно.

                                                          В любом случае — досвидания. У нас свободная страна, вы имеете свою точку зрения, а я оставляю себе право не тратить время на ваше обущение.
                                                            0
                                                            Подозреваю. Почитываю иногда ваш блог. Иногда с интересном, иногда с иронией.
                                                            В любом случае — автор который не может сказать пару плюсов, используемой им технологии (а также ответить на замечания) не достоин внимания.
                                      0
                                      тут есть ещё один мега-приятный побочный эффект. в FF с плагином ImagesLikeOpera интегрированные картинки показываются всегда, независимо от настроек плагина.
                                        0
                                        Ага :) Пользователи будут удивлены))
                                          0
                                          Кстати этим достигается показ капчи и для экономящих на картинках.
                                        0
                                        Есть ещё вот такая ссылочка

                                        http://www.hedgerwow.com/360/dhtml/base64-image/demp.php
                                          0
                                          Да, похоже этот велосипед уже изобретён.
                                            0
                                            Я не к тому что, кто-то кого-то опередил. Сие мне неизвестно.
                                            Просто там для рендера картинки в IE используется VML. Что может-быть кому-то небезинтересно.
                                              0
                                              Да, спасибо, но там совсем о другом.
                                              0
                                              Вы посмотрите, там совершенно другой принцип (откройте под IE) и картинка не внедряется, по сути.
                                                0
                                                Внедряется. Вы исходник посмотрите
                                                  0
                                                  Вы под IE исходник смотрите?
                                                    0
                                                    Исходник имеется ввиду - http://www.hedgerwow.com/360/dhtml/base64-image/code.txt

                                                    вы в исходнике HTML страницы ничего не увидите т.к. IE покажет только HTML-часть от всего MIME документа
                                                      0
                                                      Выкачал wget'ом и увидел. Но принцип сильно другой — тут, по сути, два отдельных HTML: «для IE» и «для всех остальных», у меня совершенно другая идея.

                                                      А за ссылку спасибо — очень интересное решение.
                                                        0
                                                        Т.е. я был неправ — действительно, изображение внедряется.
                                                0
                                                Отличная штука, спасибо!
                                                0
                                                протестил на своем телефоне Viewty.
                                                работает, картиночка показалась.

                                                единственно, пока не вижу особого практического применения данной технологии,
                                                зачем оно и чем лучше сжатия того же JPEG
                                                  0
                                                  Читайте выше, там всё написано. Основной плюс - вместо большого количества мелких файлов, грузится один большой. Если Вы переписывали по сети какие-то данные типа небольших картинок, то могли заметить что при переписывании их как есть скорость в разы меньше чем если засунуть их в один большой zip (который может занимать и больше, т.к. jpeg зипом не сожмёшь).
                                                    0
                                                    Если не сложно, можно в цифрах?

                                                    Допустим, на странице используется 10 картинок, общий объем которых составит 10KB.
                                                    Если использовать данную технологию, какой будет вес вашего одного файла?
                                                      0
                                                      Зависит от того используется ли сжатие GZip или нет. Если используется - то около эти самых 10 килобайт. А чтобы дать точный ответ о разнице в весе и скорости загрузки нужно провести серьёзное тестирование с разным количеством встроенных картинок и разным их весом. Без этого любые утверждения - лишь предположения.
                                                  0
                                                  Хм. Я подобный подход уже применял, немного переписав png.htc, так как в нем нужен прозрачный гифиг, а делать запрос не было никакого желания.

                                                  Насчет уменьшения кол-ва http запросов, скажу просто - используйте css sprites. Самое то для бэкграундов и иконок. Я вообще объединяю все какие только возможно оформительские изображения в один файл.
                                                    0
                                                    Прочитайте статью ссылку на которую я дал, там перечислены все плюсы, а не только тот, который для вас не актуален.
                                                    0
                                                    Огромное спасибо за инфу! Это просто суперская фишка! Тем более, раз она везде поддерживается..
                                                      0
                                                      в теге <embed не работает :(
                                                        0
                                                        В каком смысле? Вы про что?
                                                          0
                                                          <embed src="data:application/x-shockwave-flash;base64,...b64data...." type="application/x-shockwave-flash" />
                                                            0
                                                            Насколько я знаю, embed сейчас уже не нужен.

                                                      Only users with full accounts can post comments. Log in, please.