Pixrael Posted July 8, 2019 Share Posted July 8, 2019 In order to deceive the browser images cache in a javascript image src update, I use this htaccess trick to force the browser to reload "new" image from the server, the number es a time() var. I want that Apache rewrite this request: /site/downloads/9VefFf6vstUR0q1ywzPgjXw4PfAgYqGp-1562618833.png to this: /site/downloads/9VefFf6vstUR0q1ywzPgjXw4PfAgYqGp.png and this is my declaration in htaccess: <IfModule mod_rewrite.c> RewriteEngine on RewriteRule ^site/downloads/([a-zA-Z0-9]+)-([0-9]+)$ site/downloads/$1.png [R=302,NC,L] </IfModule> But I don't know if it well defined, or if the PW htaccess is in conflict with this configuration.. PW show me the 404 page and the server don't send the picture url back. Any idea? Link to comment Share on other sites More sharing options...
LostKobrakai Posted July 9, 2019 Share Posted July 9, 2019 I wouldn't do a 302 for the operation. This essentially doubles the amount of requests the browser needs to do for images and I'm not even sure if it would actually cache-bust anything. Rather rewrite the url only internally so apache serves the correct file under the incoming url with cache-busting. 2 Link to comment Share on other sites More sharing options...
Pixrael Posted July 9, 2019 Author Share Posted July 9, 2019 That mod_rewrite route don't works.. but (for the records) the following trick works smoothly ? <FilesMatch "^([a-zA-Z0-9]+)-([0-9]+)\.png$"> FileEtag None <ifModule mod_headers.c> Header Unset ETag Header Set Cache-Control "max-age=0, no-store, no-cache, must-revalidate" Header Set Pragma "no-cache" Header Set Expires "Thu, 1 Jan 1970 00:00:00 GMT" </ifModule> </FilesMatch> Link to comment Share on other sites More sharing options...
MoritzLost Posted July 9, 2019 Share Posted July 9, 2019 @Pixrael A simpler approach that doesn't require any server-side adjustments at all would be to include the cache-busting parameter as a query variable instead. For example: /site/downloads/9VefFf6vstUR0q1ywzPgjXw4PfAgYqGp.png?v=1562618833 I use something like this during development for my CSS / JS assets, so the browser downloads those anew for each request and I see all changes immediately ... The browser will not use the cached image if the query string differs. This way you don't need to rewrite any URLs in Apache. I would also strongly advise not to go with the second approach (using HTTP-headers to disable caching), as this way the images can never be cached and reused, which means your site takes a major performance hit. Can I ask why you need to do this at all? If the browser has already loaded the image, why force it to load it again? 1 Link to comment Share on other sites More sharing options...
dragan Posted July 9, 2019 Share Posted July 9, 2019 17 minutes ago, MoritzLost said: I use something like this during development for my CSS / JS assets, so the browser downloads those anew for each request and I see all changes immediately ... On a sidenote: You can also disable caching while Chrome inspector is open inside the settings: (of course, if you're testing with several other browsers plus mobile devices at the same time, the query-string approach is better) 2 Link to comment Share on other sites More sharing options...
Pixrael Posted July 9, 2019 Author Share Posted July 9, 2019 @MoritzLost Thanks for your comments. The first thing I tried was this ?v=XXXX technique, but do not works 100%, at least in chrome (several days testing that) not always reload the file. I don't know why, maybe chrome use more aggressive approach to save bandwidth or for speed.. "why force it to load it again?" .. because this is a tool that generate a picture to download, the customer can modify the tool paramaters and regenerate the picture again infinitely.. I don't want to create new pictures each time the user click the generate button (to save disk space at server), my approach is to create only one picture per user session, and use the token value as file name, so the tool overwrite it each time the picture is regenerate. I use ajax for that and with the response I change the src attribute in an image element to display the result.. this is the reason why I need that image must be forced to download each time when I change the src attribute.. Oh, this description looks a little complicated.. I explain correctly? 1 Link to comment Share on other sites More sharing options...
MoritzLost Posted July 9, 2019 Share Posted July 9, 2019 @Pixrael Thanks, that makes perfect sense. Are you sure the query parameter doesn't work? It really should, since it's a different request and may return different results for some services. Maybe Chrome is employing some heuristics to determine that it's always the same image ... though it isn't in your case ... I don't know, sounds curious. In any case, your HTTP-header method is probably the best approach for this scenario! Though you really only need the Cache-Control header; Expires, ETag and and Pragma are superfluous except for the most legacy of legacy browsers ? @dragan Firefox Developer Edition master race! ? Though I don't always have the Developer Tools open while writing my templates, and as you said I frequently need to test on other devices, so I prefer the caching busting approach. I usually have a $config->theme_version parameter in my config that gets appended to each CSS / JS URL, this way I can also easily invalidate caches on live sites when I push an update. During development (coupled to $config->debug) I just append the current timestamp, so the parameter changes for each request. 1 Link to comment Share on other sites More sharing options...
Pixrael Posted July 9, 2019 Author Share Posted July 9, 2019 A solution that I also thought was to send the generated image using base64 data in the response, but even though it served to display the result to the user, I need a fixed URL since the purpose of the tool is that once the image is the desired one, the user can import it into a third application using that URL, each image will be valid only for 24hr, after that it will be deleted from the server using cron jobs Link to comment Share on other sites More sharing options...
dragan Posted July 9, 2019 Share Posted July 9, 2019 You could use a simple PHP script that serves the image with readfile() and set appropriate headers in that script. Maybe setup a dummy PW page with URL-segments enabled (or use a plain old query string) that will act as a "gateway" to those images. If you don't need to have the exact same filename on each request (download), then you you could even create the filename dynamically each time with adding / injecting time() or microtime() to the filename PHP will create for you: header('Content-Disposition: attachment; filename="'.basename($file).'"'); 1 Link to comment Share on other sites More sharing options...
horst Posted July 9, 2019 Share Posted July 9, 2019 @MoritzLost, I use the lastmodified timestamp of the css or js file as cachebusting value. This way the files gets reloaded when needed, but can be cached in dev and live sites. 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now