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

10

这应该足够简单,但我折腾了几个小时后,仍然无法使其工作。到目前为止,我的所有尝试都导致图像在Firefox中变得“损坏或截断”。

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

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


将图像进行Base64编码,并将其存储在localStorage中:
在这个例子中,我使用的是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 id="documentHolder" alt="Image view placeholder" src="" />


然而,无论尝试多少次,火狐浏览器都会显示:

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


这个URL指向一个有效的JPEG图像,而base64Image的长度和错误信息表明var/localStorage实际上包含了似乎是Base64编码数据的内容。

有什么想法吗?

4个回答

9

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调用过程中,图像可能会被损坏。<br>附言:我正在使用asp.net,但我肯定能找到一种在服务器端编码base64图像的方法。我只是希望不那么依赖服务器端代码。 - TinkerTank
@TumbleCow:你应该比起客户端更依赖于服务器端,因为在服务器端完成的每个过程都比客户端更快和更安全。 ;) - Luca Filosofi

6

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


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

请注意,这段代码不安全,不能直接暴露在外部世界中。 我个人使用一个包装函数,从数据库中解析路径。

0

你可以通过使用HTML5画布元素,通过JavaScript获取数据URI(其中包含base64编码)。

        // 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,其中将包含图像的 base64 编码以及一个短前缀。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接