从服务器检索图像,将其存储在 localStorage 中,并显示它

Posted

技术标签:

【中文标题】从服务器检索图像,将其存储在 localStorage 中,并显示它【英文标题】:Retrieve an image from the server, store it in localStorage, and display it 【发布时间】: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"  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 编码的数据。

有什么想法吗?

【问题讨论】:

【参考方案1】:
演示: http://so.lucafilosofi.com/retrieve-an-image-from-the-server-store-it-in-localstorage-and-display-it

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);

?>

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

Base 64 encode vs loading an image file How to encode image data within an html file? How can you encode a string to Base64 in JavaScript? Get image data in JavaScript?

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 传递文件名,让浏览器缓存完成工作。

【讨论】:

以上是关于从服务器检索图像,将其存储在 localStorage 中,并显示它的主要内容,如果未能解决你的问题,请参考以下文章

Laravel + Dingo + JWT + cors 和 OPTIONS 方法

如何使用objective-c从CloudKit中的资产字段中检索图像

使用 Angular 7 从 Firebase 存储中检索图像

如何将 JSON 数据存储和检索到本地存储中?

在反应中使用异步等待从firebase存储中检索图像

我可以从服务器检索数据并将其存储在核心数据中吗?