代码说

code is poetry

代码说    
碎碎念:世界很大,世界很小。  换一换

又一次有趣的搜索经历

作者:coderzheng 发布于:2014-12-30 1:51 Tuesday 分类:other  阅读模式

在查看wampserver集成环境下默认的/www/index.php源码时,发现了一件有意思的事情:页面中显示图片的部分使用了比较特殊的方式,下面是程序中的部分代码:
// images
$pngFolder = <<< EOFILE
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAA3NCSVQICAjb4U/gAAABhlBMVEX//v7//v3///7//fr//fj+/v3//fb+/fT+/Pf//PX+/Pb+/PP+/PL+/PH+/PD+++/+++7++u/9+vL9+vH79+r79+n79uj89tj89Nf889D88sj78sz78sr58N3u7u7u7ev777j67bL67Kv46sHt6uP26cns6d356aP56aD56Jv45pT45pP45ZD45I324av344r344T14J734oT34YD13pD24Hv03af13pP233X025303JL23nX23nHz2pX23Gvn2a7122fz2I3122T12mLz14Xv1JPy1YD12Vz02Fvy1H7v04T011Py03j011b01k7v0n/x0nHz1Ejv0Hnuz3Xx0Gvz00buzofz00Pxz2juz3Hy0TrmznzmzoHy0Djqy2vtymnxzS3xzi/kyG3jyG7wyyXkwJjpwHLiw2Liw2HhwmDdvlXevVPduVThsX7btDrbsj/gq3DbsDzbrT7brDvaqzjapjrbpTraojnboTrbmzrbmjrbl0Tbljrakz3ajzzZjTfZijLZiTJdVmhqAAAAgnRSTlP///////////////////////////////////////8A////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9XzUpQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAB90RVh0U29mdHdhcmUATWFjcm9tZWRpYSBGaXJld29ya3MgOLVo0ngAAACqSURBVBiVY5BDAwxECGRlpgNBtpoKCMjLM8jnsYKASFJycnJ0tD1QRT6HromhHj8YMOcABYqEzc3d4uO9vIKCIkULgQIlYq5haao8YMBUDBQoZWIBAnFtAwsHD4kyoEA5l5SCkqa+qZ27X7hkBVCgUkhRXcvI2sk3MCpRugooUCOooWNs4+wdGpuQIlMDFKiWNbO0dXTx9AwICVGuBQqkFtQ1wEB9LhGeAwDSdzMEmZfC0wAAAABJRU5ErkJggg==
EOFILE;

//affichage des images
if (isset($_GET['img']))
{
    switch ($_GET['img'])
    {
        case 'pngFolder' :
        header(" content-type:="" image="" png");
        echo base64_decode($pngFolder);
        exit();
我们看到,程序显示图片的方式和平常使用的直接引用图片路径(src="图片路径")的方式完全不同,而是采用"还原事先用base64编码过的图片字符串"来实现的。于是我想当然编写了一段代码来做测试:
$img = "./g.gif";
$str = base64_encode($img);
var_dump($str);
显示结果如下:
string 'Li9pbWFnZXMvYWpheC1sb2FkZXIuZ2lm' (length=32)
这段字符串和程序中的字符串相差太远,看来我们刚刚的思路是错误的,于是继续去php manual中搜索base64_encode函数:

很幸运得在评论部分找到了答案,原来要先用file_get_contents函数读取图片的二进制代码,再base64_encode才行。 但是同时又发现了一个有意思的事情: 上面的代码为img标签赋值的时候格式是这样的:
<img src='data:image/png;base64,...
这种方式见所未见啊!
于是开始百度+google,终于在这篇文章中找到了答案:
http://blog.csdn.net/samqingqing/article/details/7532141
大家可能注意到了,网页上有些图片的src或css背景图片的url后面跟了一大串字符,比如:data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAYAAABIdFAMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAHhJREFUeNo8zjsOxCAMBFB/ KEAUFFR0Cbng3nQPw68ArZdAlOZppPFIBhH5EAB8b+Tlt9MYQ6i1BuqFaq1CKSVcxZ2Acs6406KUgpt5/ LCKuVgz5BDCSb13ZO99ZOdcZGvt4mJjzMVKqcha68iIePB86GAiOv8CDADlIUQBs7MD3wAAAABJRU5ErkJggg%3D%3D。那么这是什么呢?这是Data URI scheme。
Data URI scheme是在RFC2397中定义的,目的是将一些小的数据,直接嵌入到网页中,从而不用再从外部文件载入。比如上面那串字符,其实是一张小图片,将这些字符复制黏贴到火狐的地址栏中并转到,就能看到它了,一张1X36的白灰png图片。
在上面的Data URI中,data表示取得数据的协定名称,image/png 是数据类型名称,base64 是数据的编码方法,逗号后面就是这个image/png文件base64编码后的数据。
文章末尾,作者指出了使用这种方式显示图片的优缺点:
我们把图像文件的内容直接写在了HTML 文件中,这样做的好处是,节省了一个HTTP 请求。坏处呢,就是浏览器不会缓存这种图像。大家可以根据实际情况进行自由取舍。
但是问题并没有结束,RFC是个什么东西?为什么它定义的标准浏览器会支持?
继续搜索。。。(此处省略N字),最后知道了大概的情况是:html这门语言是由IETF组织发布的,在发布之前该组织会先通过一系列的文档(RFC)或者称为征求修正意见书,最后才制定统一的标准。而随着html语言向xhtml、html5过渡,这些文档便成了一个系列。

PS:关于这个部分,最终的标准是在html4.01说明书中给出的。以下是部分截图:


参考阅读:
RFC2397:https://tools.ietf.org/html/rfc2397
data uri scheme:http://en.wikipedia.org/wiki/Data_URI_scheme
html4.0.1:http://www.w3.org/TR/1999/REC-html401-19991224/struct/objects.html#h-13.3.1

标签: other

你可以发表评论、引用到你的网站或博客,或通过RSS 2.0订阅这个博客的所有文章。
上一篇: php中的Fileinfo扩展  |  下一篇:从陈皓的"痛恨手册"说起