0

I am currently working on a online auction website (Sorry but I can not share the link here). On the list of products, our client want the product image to update dynamically via real time when modified from the back-end. The solution bellow does the trick:

var nocache = new Date().getTime();             
$('#auction_id_' + aucId + ' img#' + imgID).attr("src", 'ItemPics/t' + new_image_url + '?' + nocache);

But when the user visits the product and then clicks on the back button to go back to the product list page - the cache of the product image is not cleared and the old image is back.

I can not disable the caching on the website since it causes too much loading on the client side.

(1) I have thought about creating a hidden iframe with the image as SRC and then refreshes during real time. (2) Simply reloading the page wont solve the problem so I also thought about manipulating a Ctrl + F5 using JavasSript to force request new image data when the users clicks on the back button = but I don't think any of these is the right way to do it.

Any ideas would be greatly appreciated, thanks!

Carl
  • 805
  • 12
  • 24
  • You're probably going to have to come up with an Asynchronous Solution, but it's hard to tell what you are looking for. You don't want the last image the user looked at when they visited your page? You want the first one? We are not seeing how these images are changing. – StackSlave Oct 06 '15 at 03:43
  • @PHPglue I want the new image, that was appended via real time, to be cached so when the users clicks on the back button, they see the new image and not the old image – Carl Oct 06 '15 at 03:50
  • You can just make a function to pull up a random image. – StackSlave Oct 06 '15 at 03:56
  • @PHPglue That wont work either, previous developers of the site programmed it in a way that the image name stays the same even when updated on the back-end. – Carl Oct 06 '15 at 04:00
  • Possible duplicate of [After travelling back in Firefox history, javascript won't run](http://stackoverflow.com/questions/2638292/after-travelling-back-in-firefox-history-javascript-wont-run). So the solution is to bind your function in the `window.onpageshow` event. – Kaiido Oct 06 '15 at 04:18

3 Answers3

1

You could probably have a configuration in your webserver that returns an HTTP header for image requests using Cache-Control: no-cache, max-age=0, must-revalidate, no-store This will force the browser to not store the image data in cache i believe.

Check out how cache-control headers are handled in firefox: https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching_FAQ

NullHappens
  • 425
  • 2
  • 8
  • Hi, thank you for your answer, but "I can not disable the caching on the website since it causes too much loading on the client side." I am looking for a way to clear the cache of just one image (not all images) and then replace it with the updated image which is dynamically loaded by the real time. – Carl Oct 06 '15 at 05:25
0

The problem you are facing is not that the image is cached, but that the whole page is.
So when you come back from history, the scripts are not executed and the image still has the same no-cache parameter (see this answer for more info).

One solution to workaround this is to use the window.onpageshow event handler (with a lack of support for IE<11 ) or to call an empty function in the window.onunload event handler.

if('onpageshow' in window){
  window.onpageshow = changeImgSrc;
}else {
  window.onload = changeImgSrc;
  window.onunload = function(){};
}
Community
  • 1
  • 1
Kaiido
  • 123,334
  • 13
  • 219
  • 285
0

Thank you all, my coworker was already able to solve the problem:

In your product list page, add a unique ID to your images:

<img src = "images/img1.jpg" id = "image_<?php echo $imageID; ?>" />

In your backend, when the update image button is clicked, store the new image on a session variable:

session_start();
$_SESSION['modified_item_images'][$ItemID] = $strNewPicName;

Then in your product list page, store the updated images array into a JavaScript variable:

var modified_item_images = <?php echo json_encode($_SESSION['modified_item_images']); ?>;

Then loop though each item and add a time stamp at the end of each updated image link:

$(document).ready(function() {

// Append updated images on back button click
if(modified_item_images){
    $.each( modified_item_images, function( key, image_src ){
        var nocache = new Date().getTime(); 
        $('body').find('#image_' + key).attr('data-original', 'ItemPics/t' + image_src + '?' + nocache);
    });
}

So when a user clicks on the product and hits the Back button of their browser, we will check if there are updated images stored in the session variable, if yes then we re-append them with a new time stamp to prevent the browser from rendering the old images from cache. This will only apply to specific images that were dynamically modified which solves the problem.

Carl
  • 805
  • 12
  • 24
  • 1
    I frankly doubt this solution does work : When the back button is pressed, there is no new call to server, it is served from the [bfcache](https://developer.mozilla.org/En/Working_with_BFCache). The jQuery`.ready()` won't fire either. Alos, not directly related, but the question was about js and in no mean about php. – Kaiido Oct 07 '15 at 00:16
  • @Kaiido You forgot that the PHP script was already run by the page before the back button. It's working for me and I hope others find it useful too. – Carl Oct 08 '15 at 01:21
  • But if the image is updated while user is on the "next" page and then he goes back to the "main" page, then the image he'll see won't be the updated one. The request to $_SESSION is only done at load, not if bfcached – Kaiido Oct 08 '15 at 01:22
  • @Kaiido The flow is like this:: 1) Admin user change an item image on the website, 2) Users navigating thru the product list see the image changing dynamically with the help of real time (This is where the session get set as well). 3) Single user clicks on the product that changed dynamically on his screen, 4) From the single product page, user clicks on the back button to go back to the list of products. 5) The script will read the session that got set on step 2 and appends an image with a unique GET parameter to prevent the browser from rendering the cached version of the image. – Carl Oct 09 '15 at 01:50
  • So if I got it clearly, your issue was that : let's call `c` the client, `o` the original image, `u` the updated one thanks to the no-cache workaround. `c` comes to `index`, downloads `o`, which is then updated to `u`. When `c` goes to `page2`, and then comes back to `index` via back-button, he sees `o` instead of `u`. Is that correct? If then, your question was unclear and this behaviour is not the correct one since the ``' src should be the `url+?no-cache` one. Anyway, the solution I gave you would always re-execute the no-cache workaround and should do the job in 6 js lines. – Kaiido Oct 09 '15 at 06:02