Force image caching with javascript

2019-04-22 05:57发布

问题:

I am trying to clone an image which is generated randomly. Although I am using the exact same url a different image is load. (tested in chrome and firefox)

I can't change the image server so I am looking for a pure javascript/jQuery solution.

How do you force the browser to reuse the first image?

Firefox:

Chrome:

Try it yourself (maybe you have to reload it several times to see it)

Code: http://jsfiddle.net/TRUbK/

$("<img/>").attr('src', img_src)
$("<div/>").css('background', background)
$("#source").clone()

Demo: http://jsfiddle.net/TRUbK/embedded/result/

回答1:

You can't change the image server if it isn't yours, but you can trivially write something on your own server to handle it for you.

First write something in your server-side language of choice (PHP, ASP.NET, whatever) that:

  1. Hits http://a.random-image.net/handler.aspx?username=chaosdragon&randomizername=goat&random=292.3402&fromrandomrandomizer=yes and downloads it. You generate a key in one of two way. Either get a hash of the whole thing (MD5 should be fine, it's not a security-related use so worries that it's too weak these days don't apply). Or get the size of the image - the latter could have a few duplicates, but is faster to produce.
  2. If the image isn't already stored, save it in a location using that key as part of its filename, and the content-type as another part (in case there's a mixture of JPEGs and PNGs)
  3. Respond with an XML or JSON response with the URI for the next stage.

In your client side-code, you hit that URI through XmlHttpRequest to obtain the URI to use with your images. If you want a new random one, hit that first URI again, if you want the same image for two or more places, use the same result.

That URI hits something like http://yourserver/storedRandImage?id=XXX where XXX is the key (hash or size as decided above). The handler for that looks up the stored copies of the images, and sends the file down the response stream, with the correct content-type.

This is all really easy technically, but the possible issue is a legal one, since you're storing copies of the images on another server, you may no longer be within the terms of your agreement with the service sending the random images.



回答2:

The headers being sent from your random image generator script include a Cache-Control: max-age=0 declaration which is in essence telling the browser not to cache the image.

You need to modify your image generator script/server to send proper caching headers if you want the result to be cached.

You also need to make sure that the URL stays the same (I didn't look at that aspect since there were tons of parameter being passed).



回答3:

You can try saving the base64 representation of the image.

Load the image in an hidden div/canvas, then convert it in base64. (I'm not sure if a canvas can be hidden, nor if it is possible to convery the img using html4 tag) Now you can store the "stringified" image in a cookie, and use it unlimited times...



回答4:

There seems to be two workarounds:

  1. If you go with the Canvas method, see if you can get the image to load onto the Canvas itself so that you can manipulate the image data directly instead of making a 2nd http request for the image. You can feed the image data directly onto a 2nd Canvas.
  2. If you're going to build a proxy, you can have the proxy remove the No-Cache directive so that subsequent requests by your browser use the cache (no guarantees here - depends on browser/user settings).


回答5:

First off, you can "force" anything on the web. If you need to force things, then web development is the wrong medium for you.

What you could try, is to use a canvas element to copy the image. See https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Using_images for examples.



回答6:

Tell it to stop getting a random image, seems to work the way you want when I add this third replace call:

// Get the canvas element.
var background = ($("#test").css('background-image')),
img_src = background.replace(/^.+\('?"?/, '').replace(/'?"?\).*$/, '').replace(/&fromrandomrandomizer=yes/,'')  


回答7:

try:

var myImg = new Image();
myImg.src = img_src;

and then append "myImg" to where you want:

$(document).append(myImg);


回答8:

I did this with your fiddler scripts and got the same image every time

#test {
background:url(http://a.random-image.net.nyud.net/handler.aspx?username=chaosdragon&randomizername=goat&random=292.3402&fromrandomrandomizer=yes);
width: 150px;
height: 150px;

}

note the .nyud.net after the domain name.