【问题标题】:Retrieve an image from the server, store it in localStorage, and display it从服务器检索图像,将其存储在 localStorage 中,并显示它
【发布时间】:2011-07-18 20:23:09
【问题描述】:

这应该很简单,但是在与它搏斗了几个小时后,我仍然无法让它工作。根据 firefox 的说法,到目前为止,我所有的尝试都导致图像“损坏或被截断”。

使用 jquery-ajax 调用从服务器检索图像:

 $.ajax({
                async: false,
                url: db[key]["DocumentLink"],
                success: function (result2) {


Base64对图像进行编码,并将其存储在localStore中:
在这个例子中,我使用了 jquery base64-encoding 插件,但我已经尝试了几个。

                        var dbKey = "Doc " + db[key]["ID"] + " " + db[key]["Title"];
                        console.log("storing: " + db[key]["DocumentLink"] + " in " + dbKey + "\n");
                        localStorage.removeItem(dbKey);
                        var base64Image = $.base64Encode(result2);
                        console.log(base64Image.length);
                        localStorage.setItem(dbKey, base64Image);
                       console.log("is stored: " + db[key]["DocumentLink"] + " in " + dbKey + "\n");
                }
})


显示带有数据 url 的图像:

function openImageFromDB(dbKey) {
    console.log("Trying to display image with key " + dbKey);
    var base64Img = localStorage.getItem(dbKey);
    document.getElementById("documentHolder").src='data:image/jpeg;base64,' + base64Img;
}


对应的img:

 <img id="documentHolder" alt="Image view placeholder" src="" />


但是,每次尝试时,Firefox 都会显示:

Image corrupt or truncated: data:image/jpeg;base64,77+977+977+977+9a<... much longer string>


Url: 指向一个有效的 jpeg 图像,base64Image.length 和错误消息显示 var / localStorage 实际上包含似乎是 base64 编码的数据。

有什么想法吗?

【问题讨论】:

    标签: javascript ajax image html base64


    【解决方案1】:

    Javascript(AJAX 调用)

    function LoadImg(filename) {
        var xmlhttp;
        if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp = new XMLHttpRequest();
        } else { // code for IE6, IE5
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {     
                document.getElementById("documentHolder").src = "data:image/png;base64," + xmlhttp.responseText;
            }
        };    
        xmlhttp.open("GET", 'load.php?LoadImg='+filename );
        xmlhttp.send(null);
    }
    

    PHP (load.php)

    <?php
     if (isset($_GET['LoadImg'])) {
      header("Content-Type: image/png");
      $file = file_get_contents($_GET['LoadImg']);
      echo base64_encode($file);
    }
    ?>
    

    阅读本文可能对您有所帮助:

    PS:可能你的Base64有误?

    【讨论】:

    • 感谢您简洁的回答。请注意,通过这种方式,图像仍在服务器端转换为base64。我想在客户端转换它,但我开始相信图像可能会在 AJAX 调用的过程中以某种方式被破坏。
      p.s. - 我正在使用 asp.net,但我绝对应该能够找到一种在服务器端编码 base64 图像的方法。我只想减少对服务器端代码的依赖。
    • @TumbleCow:与服务器端相比,您绝对应该更少依赖客户端。在服务器端创建的每个进程都比客户端更快、更安全。 ;)
    【解决方案2】:

    事实证明,AJAX 不能用于可靠地传输二进制数据。解决方案是在服务器端运行Base64编码,并通过AJAX传输生成的字符串。

    上面的 php 代码有效。对于正在寻找 ASP.Net / C# 解决方案的人:

        public string Image(string relpath)
        {
            Response.ContentType = "image/jpeg";
    
            string base64;
            string filename = Request.PhysicalApplicationPath + relpath;
            try
            {
                using (var fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
                {
                    var buffer = new byte[fs.Length];
                    fs.Read(buffer, 0, (int)fs.Length);
                    base64 = Convert.ToBase64String(buffer);
                }
            }
            catch (IOException e)
            {
                return filename + " / " + e.Message;
            }
            return base64;
        }
    

    请注意,直接向外部世界公开此代码是不安全的。 我个人使用一个包装函数来解析来自 db 的路径。

    【讨论】:

      【解决方案3】:

      您可以使用 HTML5 画布元素通过 JavaScript 获取数据 uri(将包含 base 64 编码)。

              // I'm assuming here you've put the image in an <img> tag on the page already.
              // If not, you'll need to adapt this a bit, or perhaps this approach is just
              // not right for your situation.
              var image = document.getElementById('id-of-image-you-want');
      
              var canvas = w.document.createElement("canvas"); 
              canvas.width = image.width;
              canvas.height = image.height;
      
              var ctx = canvas.getContext("2d");
              ctx.drawImage(image, 0, 0);
              try {
                  var dataUri = canvas.toDataURL();    
              } catch (e) {
                  console.log("D'oh!"); // Improve this error handling, obviously.
              }
      

      dataUri 现在将包含图像的数据 uri,其中将包含图像的 base 64 编码以及短前缀。

      请务必添加对画布支持的检测。 IE 8 及更早版本不支持。

      【讨论】:

        【解决方案4】:

        浏览器的大小限制不是 localStorage 的 5MB 限制。 &lt;img src="data:image/jpeg;base64,..."&gt; 的数据也受到限制,通常远小于 5MB。解决这个问题的最简单方法是通过 localStorage 传递文件名,让浏览器缓存完成工作。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-10-21
          • 1970-01-01
          • 2015-11-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多