I have a file that I link to from my website like
<a href="http://example.com/myfile.txt>View!</a>
However, this file changes very frequently and when the link is clicked, the browser loads the cached version of the file, not the actual file.
Is there a way so that clicking on that link will bypass the cache for that page?
Something nice like <a bypassCache href=""> would be wishful thinking.
Something nice like would be wishful thinking.
Indeed, there is something you can do from within the link: Add a random GET parameter.
View!
You could use JavaScript (or of course a server-side scripting language like PHP) to do this on a dynamic basis.
However, the far superior way would be to configure the text file's caching headers correctly in the first place on server side. Stealing the header info from Best way to disable client caching, a .htaccess file like this should work:
<Files myfile.txt>
FileETag None
<IfModule mod_headers.c>
Header unset ETag
Header set Cache-Control "store, no-cache, must-revalidate, post-check=0, pre-check=0"
Header set Pragma "no-cache"
Header set Expires "Sun, 19 Nov 1978 05:00:00 GMT"
</IfModule>
</FilesMatch>
Just put
<meta http-equiv="expires" content="0">
Into the head section of your target page and check again
The best way is to tell apache/(web server) to tell browser not allow caching of that file, if you don't have controll over that server, you could avoid cache by alter the parameters send to it, just add some numbers behind ?, for exemple the time when you created the link, this makes each url diferent, so the browser going to ignore the cache, but all links to the same file, as long as the server ignore the extra parameter. in php:
echo "<a href='http://example.com/myfile.txt?" . time() . "'>View!</a>"
Add a random number after the hyper link, such as View!
Generate a new random number each time the page loads.
You can solve your problem on server level. Set the special expiration date for txt resources (or that particular one) that fit to your requirements.
If you use apache you can read about mod_expiry for apache here
Related
I have done much research into the issue, I'm not blindly asking but I can't grasp this concept. So my website contains a single index.php file that loads data into divs via ajax so the page never refreshes and the url never changes. I now know I need links to certain content using url rewriting. The site contains posts, so for instance all posts are pulled from the db and 'site.com' is the url. But I want to be able to do 'site.com/post-one' and have that link go to that post. I am thinking first I need to append a variable to the end of the url when the dynamic content for that post is loaded as such: site.com?post=1 so from there I can use url rewrite; the problem I'm having is this. Since the content for post 1 would be loaded into a div, if I went this route, and implemented the url rewrite, would site.com/post-1 now just pull the data dynamically as well or does the page have to be static?
Your problem is that this would necessarily require the use of a hash, rather than a GET variable (because GET requires a page refresh, a hash doesn't). This is done via the usage of the window.location.hash variable in JavaScript, which is updated whenever the URL's content after a # changes (ex: if I were to change http://site.com/#lol to http://site.com/#lmao, window.location.hash would change from #lol to #lmao). Hashes are being used commonly in Ajax-based navigation sites, such as Twitter (I think Google's implementing it as well).
If you're using jQuery, you should try the jQuery BBQ plugin which will allow you to do things such as hash change detection (otherwise, you will have to implement some kind of similar engine yourself, because it will be needed for any kind of hash-based navigation).
You should remember, though, that this doesn't have anything to do with mod_rewrite, thus you shouldn't need to add any kind of rewrite rules. All your work (fetching data, etcetera) would be done through Ajax XML HTTP requests, rather than common HTTP requests.
Using this, you could make your url look like http://site.com/#!/post/1 (this could go whichever format you'd like, such as http://site.com/#!/p/this-is-the-posts-title) instead of http://site.com/?post=1, although you would be missing on http://site.com/post/1.
Your idea of using mod_rewrite seems sound. If you used a rewrite directive which passes part of the URI as a POST variable into your index.php, couldn't you throw some code into the top of your index file which checks for that data and then dynamically generates the ajax to dump into the divs?
Ex:
RewriteRule ^(.*)$ index.php?post=$1 [L]
Index.php:
<?php if (isset($_POST['post'])) { ?>
$.ajax({
**grab post content dump into div**
});
<?php } ?>
Also, don't forget to sanitize your $_POST data before processing it.
My application generates a dynamic link to any PDF files that are associated with a product. The link is presented like this:
Brochure
If the user right-clicks and selects "Download Linked File As" (or its equivalent), the file is presented with a ".pdf.png" extension in Google Chrome and Safari. Firefox works appropriately, not sure about Internet Explorer.
I want Firefox and Chrome to know that it is a PDF. Because obviously users are going to try to download these, they are going to save it with the wrong extension, and they won't be able to open the file.
Assuming you are using "send_data" from within a rails controller to serve the file might I suggest:
send_data(
data,
:filename => "filename.pdf",
:disposition => "attachment",
:type => 'application/pdf'
)
Where "data" is the contents of the PDF.
For more information checkout the following link:
http://api.rubyonrails.org/classes/ActionController/DataStreaming.html#method-i-send_data
send proper headers in some scripting lang like php or user .htaccess
<Files *.pdf>
ForceType application/pdf
Header set Content-Disposition attachment
</Files>
Have you heard of the content-disposition header? It allows you to tell the browser to ask the user what to do with the file, rather than try and handle it by itself. I don't think it is part of the HTTP spec, but it is documented by the IETF under RFC 2183.
You should be able to use whatever language you are using to alter the HTTP headers before they go to the client. The header you add will look something like this:
Content-Disposition: attachment; filename=filename.pdf
You might also need a Content-Type header:
Content-Type: application/pdf
I have a problem where users are reporting that their images aren't being uploaded and the old ones are still there. On closer inspection the new images are there, they just have the same name as the old one. What I do on the upload is that I rename the images for SEO purposes. When they delete an image the old index becomes available and is reused. Therefore it has the same image name.
Is there a way to (i thought maybe there might be a meta tag for this) to tell the browser to not use its cahce?
The better answer is to rename the image to something totally new. I will get working on that but in the mean time is the quick solution while I work on the bigger problem.
Append a query string with an arbitrary unique number (or time, or version number, etc.):
<img src="image.png?80172489074" alt="a cool image" />
This will result in a new request, because of the different URL.
It's tough. You really want images to be cached, but then you don't want to cache them once a new ones available:
Using expires header with a date in the past prevents any caching. Bad
Adding a "cache busting" parameter ?342038402 can fix the problem, but can also prevent the image ever from being cached, which is not what you want. Bad.
Using expires header with a short (lets say 1 hr) expires is better... after an hour the user will see the image, but your web server won't have to serve it every time. Compromise, but what time works? Not really feasible.
The solution? I can think of two good options:
Look into eTags, and your ability to use them. These are designed for this situation. The browser will explicitly ask your server whether the file is up-to-date or not. You can just turn this on in apache if you don't have it aleady.
Create a new URL for each new image (and use a far-future expires header). This is what you are working on.
My favourite PHP solution:
<img src="<?php echo "image.jpg" . "?v=" . filemtime("image.jpg"); ?>" />
every change of file "create" a new version of the file
Append the current datetime to the image src:
<img src="yourImage.png?v=<?php echo Date("Y.m.d.G.i.s")?>" />
You can put http-equiv in <meta> tag which will tell browser not to use cache (or even better -- use it in some defined way), but it is better to configure server to send proper http cache headers. Check out article on caching.
Still, some browsers might not support all of http standard, but I believe it's the way to go.
Another powerfull solution:
<img src="image.png?v=<?php echo filemtime("image.png"); ?>" />
This print the "last-modification-timestamp" on the path.
New version --> Download new image
Same version --> Take cache's one
Go Random. Just use some random number and append it with image filename.
<img src="image.jpg?<?=rand(1,1000000)?>">
you can control the cache behaviour by playing with the HTTP headers.
setting the expires header in past would force browser to not use cached version.
Expires: Sat, 26 Jul 1997 05:00:00 GMT
You can consult the RFC to have more details.
If you look at the data that is exchanged between your browser and the server, you'll see that the browser will send a HTTP HEAD request for the images. The result will contain the modification time (but not the actual image data). Make sure that this time changes if the image changes on the server and the browser should download the image again.
in PHP you can use this trick
<img src="image.png?<?php echo time(); ?>" />
The time() function show the current timestamp. Every page load is different. So this code deceive the browser: it read another path and it "think" that the image is changed since the user has visited the site the last time. And it has to re-download it, instead of use the cache one.
It sounds like the concern is more about the primary user seeing their new image than cache being disabled entirely? If that's the case, you can do the following:
var headers = new Headers()
headers.append('pragma', 'no-cache')
headers.append('cache-control', 'no-cache')
var init = {
method: 'GET',
headers: headers,
mode: 'no-cors',
cache: 'no-cache',
}
fetch(new Request('path/to.file'), init)
If you do this after a new image is uploaded, the browser should see those headers and make a call to the backend, skipping the cache. The new image is now in cache under that URL. The primary user will see the new image, but you still retain all the benefits of caching. Anyone else viewing this image will see updates in a day or so once their cache invalidates.
If the concern was more about making sure all users see the most up to date version, you would want to use one of the other solutions.
In PHP you can send a random number or the current timestamp:
<img src="image.jpg?<?=Date('U')?>">
or
<img src="image.jpg?<?=rand(1,32000)?>">
that was not ok result, I think this is the way to program it correct.
<td><?php echo "<img heigth=90 width=260 border=1 vspace=2 hspace=2 src=".$row['address']."?=".rand(1,999)."/>" ?></td>
I had come up with this issue some times ago. And I was getting data through JSON in AJAX.
So what I did is, I just added a Math.random() Javascript function and It worked like a charm.
The backend I used was a flask.
<img class="card-img-top w-100 d-block" style="padding:30px;height:400px" src="static/img/${data.image}?${Math.random()} ">
at least in chrome, when i hit the back button, it doesn't actually reload the page, it just uses a stored copy i guess. How can i ensure that when someone does this, the page is reloaded?
In PHP you would do this:
header('Expires: Mon, 20 Dec 1998 01:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-cache, must-revalidate');
header('Pragma: no-cache');
However, the names of the headers sent would be the same for any server-side programming language as they all eventually go over HTTP to the client.
See Wikipedia's List of HTTP Headers for information about each of these.
I haven't tried it, but you could try to send a Cache-Control HTTP header with your file. For example in PHP:
header('Cache-Control: no-cache,no-store,max-age=0');
This will tell your browsers (and caches along the way) not to cache this file under any circumstance. But delivering the previous file on clicking the back button is not necessarily considered caching and so might ignore such headers.
If you really want to avoid the back button you can try do to it with Javascript. I really don't recommend this approach - and you should step back and think about why you want to do this. That said, something like this code in your HTML body should work:
<input type="hidden" id="back_button" value="0" />
<script>
var bb = document.getElementById('back_button');
if (bb.value !== '0') {
location.href = location.href + '?rand=' + parseInt(Math.random()*9999);
}
bb.value = '1';
</script>
This will open the current page but with a 'rand' query string parameter appended to bust any caches.
If you are in the asp.net world I believe all you should need to do is
Response.Cache.SetCacheability(HttpCacheability.NoCache)
In your Page_Load
I generate some images using a PHP lib.
Sometimes the browser does not load the new generated file.
How can I disable cache just for images created dynamically by me?
Note: I have to use same name for the created images over time.
A common and simple solution to this problem that feels like a hack but is fairly portable is to add a randomly generated query string to each request for the dynamic image.
So, for example -
<img src="image.png" />
Would become
<img src="image.png?dummy=8484744" />
Or
<img src="image.png?dummy=371662" />
From the point of view of the web-server the same file is accessed, but from the point of view of the browser no caching can be performed.
The random number generation can happen either on the server when serving the page (just make sure the page itself isn't cached...), or on the client (using JavaScript).
You will need to verify whether your web-server can cope with this trick.
Browser caching strategies can be controlled by HTTP headers. Remember that they are just a hint, really. Since browsers are terribly inconsistent in this (and any other) field, you'll need several headers to get the desired effect on a range of browsers.
header ("Pragma-directive: no-cache");
header ("Cache-directive: no-cache");
header ("Cache-control: no-cache");
header ("Pragma: no-cache");
header ("Expires: 0");
Solution 1 is not great. It does work, but adding hacky random or timestamped query strings to the end of your image files will make the browser re-download and cache every version of every image, every time a page is loaded, regardless of whether or not the image has changed on the server.
Solution 2 is useless. Adding nocache headers to an image file is not only very difficult to implement, but it's completely impractical because it requires you to predict when it will be needed in advance, the first time you load any image that you think might change at some point in the future.
Enter Etags...
The absolute best way I've found to solve this is to use ETAGS inside a .htaccess file in your images directory. The following tells Apache to send a unique hash to the browser in the image file headers. This hash only ever changes when the image file is modified and this change triggers the browser to reload the image the next time it is requested.
<FilesMatch "\.(jpg|jpeg)$">
FileETag MTime Size
</FilesMatch>
If you need to do it dynamically in the browser using javascript, here is an example...
<img id=graph alt=""
src="http://www.kitco.com/images/live/gold.gif"
/>
<script language="javascript" type="text/javascript">
var d = new Date();
document.getElementById("graph").src =
"http://www.kitco.com/images/live/gold.gif?ver=" +
d.getTime();
</script>
I checked all the answers and the best one seemed to be (which isn't):
<img src="image.png?cache=none">
at first.
However, if you add cache=none parameter (which is static "none" word), it doesn't effect anything, browser still loads from cache.
Solution to this problem was:
<img src="image.png?nocache=<?php echo time(); ?>">
where you basically add unix timestamp to make the parameter dynamic and no cache, it worked.
However, my problem was a little different:
I was loading on the fly generated php chart image, and controlling the page with $_GET parameters. I wanted the image to be read from cache when the URL GET parameter stays the same, and do not cache when the GET parameters change.
To solve this problem, I needed to hash $_GET but since it is array here is the solution:
$chart_hash = md5(implode('-', $_GET));
echo "<img src='/images/mychart.png?hash=$chart_hash'>";
Edit:
Although the above solution works just fine, sometimes you want to serve the cached version UNTIL the file is changed. (with the above solution, it disables the cache for that image completely)
So, to serve cached image from browser UNTIL there is a change in the image file use:
echo "<img src='/images/mychart.png?hash=" . filemtime('mychart.png') . "'>";
filemtime() gets file modification time.
I know this topic is old, but it ranks very well in Google. I found out that putting this in your header works well;
<meta Http-Equiv="Cache-Control" Content="no-cache">
<meta Http-Equiv="Pragma" Content="no-cache">
<meta Http-Equiv="Expires" Content="0">
<meta Http-Equiv="Pragma-directive: no-cache">
<meta Http-Equiv="Cache-directive: no-cache">
I was just looking for a solution to this, and the answers above didn't work in my case (and I have insufficient reputation to comment on them). It turns out that, at least for my use-case and the browser I was using (Chrome on OSX), the only thing that seemed to prevent caching was:
Cache-Control = 'no-store'
For completeness i'm now using all 3 of 'no-cache, no-store, must-revalidate'
So in my case (serving dynamically generated images out of Flask in Python), I had to do the following to hopefully work in as many browsers as possible...
def make_uncached_response(inFile):
response = make_response(inFile)
response.headers['Pragma-Directive'] = 'no-cache'
response.headers['Cache-Directive'] = 'no-cache'
response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
response.headers['Pragma'] = 'no-cache'
response.headers['Expires'] = '0'
return response
Changing the image source is the solution. You can indeed do this by adding a timestamp or random number to the image.
Better would be to add a checksum of eg the data the image represents. This enables caching when possible.
Let's add another solution one to the bunch.
Adding a unique string at the end is a perfect solution.
example.jpg?646413154
Following solution extends this method and provides both the caching capability and fetch a new version when the image is updated.
When the image is updated, the filemtime will be changed.
<?php
$filename = "path/to/images/example.jpg";
$filemtime = filemtime($filename);
?>
Now output the image:
<img src="images/example.jpg?<?php echo $filemtime; ?>" >
i had this problem and overcoming like this.
var newtags='<div class="addedimage"><h5>preview image</h5><img src="'+one+'?nocache='+Math.floor(Math.random() * 1000)+'"></div>';
I've used this to solve my similar problem ... displaying an image counter (from an external provider). It did not refresh always correctly. And after a random parameter was added, all works fine :)
I've appended a date string to ensure refresh at least every minute.
sample code (PHP):
$output .= "<img src=\"http://xy.somecounter.com/?id=1234567890&".date(ymdHi)."\" alt=\"somecounter.com\" style=\"border:none;\">";
That results in a src link like:
http://xy.somecounter.com/?id=1234567890&1207241014
If you have a hardcoded image URL, for example: http://example.com/image.jpg you can use php to add headers to your image.
First you will have to make apache process your jpg as php.
See here:
Is it possible to execute PHP with extension file.php.jpg?
Load the image (imagecreatefromjpeg) from file then add the headers from previous answers. Use php function header to add the headers.
Then output the image with the imagejpeg function.
Please notice that it's very insecure to let php process jpg images. Also please be aware I haven't tested this solution so it is up to you to make it work.
Simple, send one header location.
My site, contains one image, and after upload the image, there not change, then I add this code:
<?php header("Location: pagelocalimage.php"); ?>
Work's for me.