0

I use the following code in the head section of my php page to load an image:

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        console.log(this.response, typeof this.response);
        var img = document.getElementById('gallery_image');
        var url = window.URL || window.webkitURL;
        img.src = url.createObjectURL(this.response);
    }
}
xhr.open('GET', '/img/loading.gif');
xhr.responseType = 'blob';
xhr.send();

That works. However, what I want to do now, is to set the image as the background image. I tried to change the line

img.src = url.createObjectURL(this.response);

into

img.style.background.src = url.createObjectURL(this.response);

but this does not work. So what should I do instead?

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
SCM
  • 45
  • 1
  • 9

2 Answers2

3

Have you also considered base64? For example, Display PNG image as response to jQuery AJAX request

On PHP:

<?php
    $img = file_get_contents('someimage.png');
    $imb64 = base64_encode($img);  
    header('Content-Type: image/png');
    echo $imb64;
    exit;
?> 

On Javascript:

    $.ajax({
        type: "POST",
        url:'myimage.php',
        contentType: "image/png",
        data: {},
        success: function(data){
            $('#myimage').css('background-image', 'url(' + 'data:image/png;base64,' + data+ ')');

        }
    });

Of course you need to change the above, its just a simple example.? Not tested as wrote/modified it to base basics

Of course you dont need to use jquery, this is just to shorten the example.. You should be able to use your xhr

Resources:

https://en.wikipedia.org/wiki/Data_URI_scheme

https://css-tricks.com/data-uris/

This method can be very handy, allows you to control hot-linking and show place holders for missing files along with the ability to control cache with a e-tag...

----------Im feeling nice-------------

    function cacheByModified($file) {
        if ($GLOBALS['VTIS']['cache']!==false) {
            $ts = filemtime($file);
            $gmt_mtime = gmdate('r', $ts);
            header('ETag: "'.md5($ts.$file).'"');
            header('Last-Modified: '.$gmt_mtime);
            header('Cache-Control: public');
            // IF HAS HEADERS
            if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) || isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
                if ($_SERVER['HTTP_IF_MODIFIED_SINCE'] == $gmt_mtime || str_replace('"', '', stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])) == md5($ts.$file)) {
                    header('HTTP/1.1 304 Not Modified');
                    if (extension_loaded("zlib") && (ini_get("output_handler") != "ob_gzhandler")) {
                        ini_set("zlib.output_compression", 1);
                    }   
                    exit;
                }
            }
        }
    }


    // Cacher.. send normal headers, check if found.. if are.. return 304 and exit.
    cacheByModified("filename.ext or some other unique id here per file..");

    // Enable gzip before sending the file
    if (extension_loaded("zlib") && (ini_get("output_handler") != "ob_gzhandler")) {
        ini_set("zlib.output_compression", 1);
    }

    // Obtain the file itself
    $img = file_get_contents('someimage.png');
    $imb64 = base64_encode($img);  

    // Send main header and output
    header('Content-Type: image/png']);
    echo $imb64;
    exit;

The above / attached code is a quick extract of my cache function, i've not tested it out side of the project as only doing this quick.. But should work if i am not mistaken.

Community
  • 1
  • 1
Angry 84
  • 2,935
  • 1
  • 25
  • 24
  • The problem here is that I want so set the background image, not the image itself – SCM Oct 22 '15 at 08:53
  • Not a problem, you can use Data URI's for CSS background – Angry 84 Oct 22 '15 at 08:55
  • I see. I tested it and in principle it seems to work, I'm just missing the data payload – SCM Oct 22 '15 at 09:11
  • was only short example, so i added the echo and headers as they are required. – Angry 84 Oct 22 '15 at 09:13
  • Wow that works! Great. Unfortunately I can't upvote right now. But I'm coming back when I have more reputation. – SCM Oct 22 '15 at 09:21
  • Its all good, just glad it worked and helped.. But look into using it further,, Eg, you can do alot of control over the images this way.. The cache part i use alot, i set a e-tag and check it against the file modified date. – Angry 84 Oct 22 '15 at 09:23
  • Yes. What I'm trying to do here is to force an image to load very early, so that I can use it as a background loading image while the real big images load. This works already pretty well: http://test.roser.li The only thing left is that the images are still loaded sequentially. What I wanted to achieve was to load all images with the loading background image. And then as soon as the structure of the website is ready, load the real images. But there I need a little bit more research :) – SCM Oct 22 '15 at 09:30
  • Make sure you balance JS in the footer of your site and CSS in the header.. Once you understand blocking, you can then organise things fairly well. Another trick i also do is combine most of my CSS / JS into single files and cache them using the same method (e-tags/php).. This helps alot as well, also dont forget G-zip compression as well.. And you can load CSS dynamically as well.. Mine starts with a styled body tag, basic JS to perform a loader.. Then the site is loaded dynamically.. It performs alot quicker and a re-fresh or navigation never gives a quick flash of white/background-color. – Angry 84 Oct 22 '15 at 09:36
0

I think the following js code will help you instead of what you have:

img.style.backgroundImage = url.createObjectURL(this.response);

Also you can see the documentation for it here.

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
Florin Pop
  • 5,105
  • 3
  • 25
  • 58