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

后端 未结 4 634
终归单人心
终归单人心 2021-02-01 10:12

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 tr

相关标签:
4条回答
  • 2021-02-01 10:41

    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.

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

        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.

    0 讨论(0)
  • 2021-02-01 10:48
    • DEMO: http://so.lucafilosofi.com/retrieve-an-image-from-the-server-store-it-in-localstorage-and-display-it

    Javascript (AJAX call)

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

    Read this may help you:

    • 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: maybe your Base64 is wrong?

    0 讨论(0)
  • 2021-02-01 10:53

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

            // 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 will now contain the data uri for the image which will contain, along with a short prefix, the base 64 encoding of the image.

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

    0 讨论(0)
  • 2021-02-01 10:56

    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.

    0 讨论(0)
提交回复
热议问题