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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5363957/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 16:52:38  来源:igfitidea点击:

Retrieve an image from the server, store it in localStorage, and display it

javascriptajaximagehtmlbase64

提问by TinkerTank

This should be simple enough, but after wrestling with it for hours, I still can't get it to work. So far, all my attempts have resulted in the image becoming 'corrupted or truncated', according to firefox.

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

Retrieve the image from the server with a jquery-ajax call:

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

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


Base64 encode the image, and store it in localStore:
In this example I'm using the jquery base64-encoding plugin, but I've tried several.


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


Display the image with a data url:


显示带有数据 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;
}


The corresponding img:


对应的img:

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


However, on every try, firefox displays:


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

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


The Url: points to a valid jpeg image, and the base64Image.length and the error message show that the var / localStorage actually contain what seems to be base64 encoded data.


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

Any ideas?

有任何想法吗?

采纳答案by Luca Filosofi

Javascript (AJAX call)

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 ( load.php )

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


Read this may help you:

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

PS:maybe your Base64is wrong?

PS:也许你Base64错了?

回答by bartonlp

Browsers have size limitations other than the localStorage limit of 5MB. The data for the <img src="data:image/jpeg;base64,...">is also restricted and is usually much less than 5MB. The easiest way around this is to just pass the file-names via localStorage and let the browsers caching do the work.

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

回答by TinkerTank

Turns out, AJAX can't be used to reliably transfer binary data. The solution is to run the Base64 encoding server-side, and transfer the resulting string through AJAX.

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

The above php-code works. For whoever is looking for a ASP.Net / C# solution:

上面的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;
    }

Please note that this code is NOT SECURE to expose directly to the outer world. I personally use a wrapper-function that parses the path from a db.

请注意,此代码不安全地直接暴露给外部世界。我个人使用一个包装函数来解析来自数据库的路径。

回答by Trott

You can get the data uri (which will contain the base 64 encoding) via JavaScript using the HTML5 canvas element.

您可以使用 HTML5 canvas 元素通过 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.
        }

dataUriwill now contain the data uri for the image which will contain, along with a short prefix, the base 64 encoding of the image.

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

Be sure to add detection for canvas support. IE 8 and older do not support it.

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