Przeglądając kod plugina Scienta ZF Debug Bar trafiłem na nieznany mi wcześniej sposób osadzania grafik w kodzie HTML. Ikony są tworzone w locie na podstawie zakodowanego przy użyciu base64 ciągu znaków, np.:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAEYSURBVBgZBcHPio5hGAfg6/2+R980k6wmJgsJ5U/ZOAqbSc2GnXOwUg7BESgLUeIQ1GSjLFnMwsKGGg1qxJRmPM97/1zXFAAAAEADdlfZzr26miup2svnelq7d2aYgt3rebl585wN6+K3I1/9fJe7O/uIePP2SypJkiRJ0vMhr55FLCA3zgIAOK9uQ4MS361ZOSX+OrTvkgINSjS/HIvhjxNNFGgQsbSmabohKDNoUGLohsls6BaiQIMSs2FYmnXdUsygQYmumy3Nhi6igwalDEOJEjPKP7CA2aFNK8Bkyy3fdNCg7r9/fW3jgpVJbDmy5+PB2IYp4MXFelQ7izPrhkPHB+P5/PjhD5gCgCenx+VR/dODEwD+A3T7nqbxwf1HAAAAAElFTkSuQmCC
Obrazek można zobaczyć wklejając powyższy kod do paska adresu np. w Firefoksie czy Operze
Jak to działa?
Powyższy sposób zapisu to tzw. data URI, zaproponowany w 1998 roku. Pozwala na dołączanie niewielkich danych bezpośrednio na stronie zupełnie jakbyśmy chcieli je wywołać z zewnątrz. Weźmy przykład z obrazkiem. Jeśli dołączamy grafikę w kodzie XHTML piszemy:
<img src=”grafika.png” />
co powoduje konieczność wykonania dodatkowego połączenia HTTP.
Możemy także napisać:
<img src=”data:image/png;base64,iV…” />
przez co eliminujemy kolejne wywołania HTTP oraz m.in. konieczność dołączania dodatkowych plików w przypadku dystrybucji kodu.
Rozwiązanie to ma swoje wady i zalety. Ich zestawienie prezentuje m.in. strona na temat data URI w wikipedii, ciekawy tekst na ten temat można znaleźć też w artykule na sitepoint.com Why The data: URI Scheme Could Help Save Your Slow Site (ciekawe są też komentarze).
Największą wadą jest brak implementacji data URI w Internet Explorerze. Wersja IE 8 to zmienia, jednak użycie jest ograniczone (mimo to dla niewielkich obrazków wystarczające). Dla wcześniejszych wersji można to obejść, jednak rozwiązanie wymaga odwołania do zewnętrznego pliku dekodującego, zatem dla każdego obrazka idzie odrębne wywołanie HTTP (ale tylko dla IE).
Jak przygotować kod obrazka? W przypadku PHP wystarczy wykorzystać przykład z wikipedii:
$contents = file_get_contents($file);
$base64 = base64_encode($contents);
Można też skorzystać ze strony www oferującej taką usługę, np. data URI kitchen czy data: URI image encoder
Do poczytania:
Czym jest URI i czym się różni od URL czy URN
Inline Images with Data URLs
IE workarounds data URI
IE8 data Protocol
pełny kod obazka widać dopiero na podglądzie żródła strony