6

I'm loading an image in an iframe and then (once the iframe is loaded) loading the image on the page. But most browsers seem to be loading the image twice. Why isn't the img tag being loading from the cache?

Something like this:

var loader = $('<iframe />').appendTo('body')[0];
loader.onload = function() {
    $('body').append('<img src="' + imgsrc + '" />');
};
loader.src = imgsrc;

http://jsfiddle.net/amirshim/na3UA/

I'm using fiddler2 to see the network traffic.

In case you want to know why I want to do this, check out this question

Community
  • 1
  • 1
Amir
  • 4,131
  • 26
  • 36

4 Answers4

0

Having an iframe is like having a separate tab, it uses another browser instance, for this reason I believe it is not using the cache.

Still if what you want is having the picture pre loaded, you can use new Image() in javascript

Fernando Diaz Garrido
  • 3,995
  • 19
  • 22
  • Yes you can just use `(new Image()).src = "http://www.example.com/myimage.jpg"` and it will preload your image. – Adam Heath Feb 12 '11 at 23:38
  • @Adam That's not what I want to do. If you read the other question, you'll understand why I want to load it in an iframe http://stackoverflow.com/questions/4926215/cancel-single-image-request-in-html5-browsers/4979270 – Amir Feb 13 '11 at 00:20
  • The cache is shared... that's why CDN networks (like google and microsoft) host stuff like jQuery in one place: http://code.google.com/apis/libraries/devguide.html – Amir Feb 13 '11 at 00:21
0

Maybe you sending HTTP headers, which prevent the caching? If you use PHP to send the image to the user and start a session, PHP will set headers forcing reloading the image all the time.

iGEL
  • 16,540
  • 11
  • 60
  • 74
  • Nope... set `use_unique_name = false` and if you watch the traffic, you'll see that it does get cached. – Amir Feb 13 '11 at 00:18
0

.htaccess can be used to improve caching and you can set headers in PHP too. I use .htaccess: if the image has been loaded once and you've made no change, it will be loaded from cache. This behavior can be set for other types of files (see below):

.htaccess

# BEGIN Expire headers
<IfModule mod_expires.c>
   ExpiresActive On
   ExpiresDefault "access plus 1 seconds"
   ExpiresByType image/x-icon "access plus 2 months"
   ExpiresByType image/jpeg "access plus 2 months"
   ExpiresByType image/png "access plus 2 months"
   ExpiresByType image/gif "access plus 2 months"
   ExpiresByType application/x-shockwave-flash "access plus 2 months"
   ExpiresByType text/css A15552000
   ExpiresByType text/javascript "access plus 2 months"
   ExpiresByType application/x-javascript "access plus 2 months"
   ExpiresByType text/html "access plus 600 seconds"
   ExpiresByType application/xhtml+xml "access plus 600 seconds"
</IfModule>
# END Expire headers
# BEGIN Cache-Control Headers
<IfModule mod_headers.c>
   <FilesMatch "\\.(ico|jpe?g|png|gif|swf)$">
   Header set Cache-Control "max-age=15552000, public"
</FilesMatch>
<FilesMatch "\\.(css)$">
   Header set Cache-Control "max-age=2678400, public"
</FilesMatch>
<FilesMatch "\\.(js)$">
   Header set Cache-Control "max-age=2678400, private"
</FilesMatch>
<FilesMatch "\\.(x?html?|php)$">
   Header set Cache-Control "max-age=600, private, must-revalidate"
</FilesMatch>

msmafra
  • 1,704
  • 3
  • 21
  • 34
0

I have tested with this new version and it works, caching is used for the second image, tested on IE7 & FF3.6. the difference is in the way i set the img src attribute in the load() jQuery callback (but why remains a mystery for me).

Be careful in this example I used a huge image to really see the difference.

$(function() {
    var use_unique_name = true;

    var imgsrc = 'http://www.challey.com/WTC/wtc_huge.jpg';
    if (use_unique_name) {
        var ts = +(new Date());
        // try replacing _= if it is there
        var ret = imgsrc.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
        // if nothing was replaced, add timestamp to the end
        imgsrc = imgsrc + ((ret == imgsrc) ? (imgsrc.match(/\?/) ? "&" : "?") + "_=" + ts : "");
    }

    var loader = $('<iframe />').appendTo('body');

    loader.load(function() {
        var img = jQuery('<img src="#"/>');
        $('body').append(img);
        img.attr('src',imgsrc);
    });

    loader.attr('src', imgsrc);
});

edit fiddle link: http://jsfiddle.net/regilero/g8Hfw/

regilero
  • 29,806
  • 6
  • 60
  • 99
  • Unfortunately, it only works for me under IE 9.0.8080. It loads the image twice on the other browsers I tested: Chrome 9.0.597.98, Firefox 3.6.13, and Safari 5.0.3. – Amir Feb 14 '11 at 17:25
  • strange, works well on FF 3.6.11, when you say it loads the image twice, you mean the image takes several seconds to load twice? – regilero Feb 14 '11 at 22:15
  • @Amir: tested with success on FF 3.6.11, Chrome 9.0.597.98, IE 7.0.5730.13, IE 8.0.7600.16385. are you completly sure that the image request takes several seconds the 2nd time? From what I saw only Safari could make this error on forced reload with no cache. – regilero Feb 15 '11 at 08:48
  • It's not consistent... when I look at the network traffic, I see that it's sometimes being loaded twice. It works most of the time in FF, but chrome (windows) loads it twice... almost always: http://rookery9.aviary.com.s3.amazonaws.com/6737000/6737250_053b.png Chrome on Linux works most of the time. IE works. Safari is inconsistent. I have a hunch, maybe it has something to do with the mime type? i.e. it might interpret it differently depending if it's or – Amir Feb 16 '11 at 01:03