I have some JS, CSS, image files on my page and I'm using cache so when I revisit my page
browser doesn't hit my server.
But when I refresh my page, browser hit the server and my server returns 304 NOT MODIFIED.
I know it's usual phenomenon but I wanna know if there is any method to prevent browser from hitting my server and just load those from the cache instead when user refresh the page.
For example when I refresh google page some of their resources are loaded from cache not 304 NOT MODIFIED.
Can anybody help web newbie :) ?
This is normal behavior and ordinarily I'd just live with it. As long as you've set the expiration or max-age settings properly then the 304 messages will only happen upon refresh, as you say. And as long as your users aren't hitting refresh regularly, then the 304 will not typically occur as people browse the site.
However, there are some situations in which you can prevent the 304 message even when the user refreshed the page.
Setting the background-image of an element through Javascript.
Using an iframe to pull content that has a max-age (note that they can still refresh the iframe by right-clicking inside it and clicking refresh).
Here's a background-image example if you want to try it out...
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<div id="example-image" style="height: 250px;"></div>
<script type="text/javascript">
$("#example-image").css("background", "white url(/images/myImage.jpg) no-repeat");
</script>
UPDATE
I was thinking AJAX GETs would work but it appears I was wrong so I've removed that from the list. In any case, the solutions I've listed above do work but they are clunky and unpleasant which is why I normally don't bother with this.
UPDATE #2
Steve Souders has some interesting experiments regarding this issue...
http://www.stevesouders.com/blog/2013/02/26/reloading-post-onload-resources/
Related
My web app runs under Tomcat, it uses AJAX requests very intensively, and during the development process I have to redeploy the web app intensively too. After the redeployment I usually simply refresh the page knowing that the user session is dropped, but I always get to the scenario described below:
Go to some page, a really big page with many JS-scripts included, that actually makes those intensive AJAX requests.
Stop Tomcat or redeploy the web app.
Refresh the page.
Enter the credentials in the sign-in form to authenticate.
Suddenly get the last AJAX request response in the browser window and the AJAX request URL in the URL bar.
Wow... It looks strange for me that AJAX request URLs appear in the URL bar along with their response in the web page display area. This actually happens to Firefox and Chrome (haven't tested it in other browsers). Unfortunately, I cannot reproduce the same behavior in a simple page written from scratch. Frankly speaking, I don't really understand what happens to such requests and why do browsers "think" if AJAX requests/responses are entered in URL bar by user...
Your possible explanations or hints for such a strange behavior are very and very appreciated. Thanks!
(Perhaps it can help: All AJAX requests are performed with jQuery 1.4.2)
I'm very sorry, as I understood later, the question is not complete, because there was another pitfall I didn't mention, so no one couldn't answer the question in principle. The reason of the bug was hiding in the... <body onunload="..."> tag definition. That was quite unexpected, but that code contained some AJAX request that must be invoked when a user leaves the page. I only realized that the authenicating module (FORM, j_security_check) returned a response (HTTP 302) containing the Location header - so that was the reason why browsers did redirects.
The exact scenario was like that:
Open the page containing <body onunload="some_ajax_here">.
Log out the app using another tab so you could stay at the same page.
Refresh the page so some ajax could be invoked - this AJAX request is not now allowed because it's a secured part of the application (you get the forwarded content of the login page).
Enter the credentials and now oops you get to the result of some ajax directly in the browser window.
As the quick fix, and I hope the final one, I added another request following that AJAX request:
$.ajax({
async: true,
method: "GET",
url: document.location.pathname + document.location.search
});
So the HTML page script simply makes self-page request the last one - j_security_check returns the Location referring the last used HTML page, and the redirect works fine. Perhaps my explanation is not clear and may be not complete or even full of mistakes, but it looks like that in general. I'm very sorry once again, and thank you #ChristopherSchultz!
I've encountered a strange bug in Chrome 19. I implemented a full-AJAX website (every non-external link is opened via AJAX request) with pushState support. I transmit the HTML snippets in AJAX via JSON format.
When I leave my site via an external link and then go back, Chrome renders cached data for that URL - the problem is, he caches the JSON content and shows that, instead of full web-page.
This is reproducible by these steps (UPDATE: I removed AJAX functionality on my website since then, so this bug does no longer appear):
Open http://beta.mirtes.cz/
Click on the second date link (16. 6. 2012 next to "It all began with a strange e-mail"). This page (you are now at http://beta.mirtes.cz/it-all-began-with-a-strange-e-mail) is loaded via AJAX.
Click on "It all began with a strange e-mail". You are redirected to an external website.
Click "Back" in Chrome after the page is completely loaded.
I try to send all AJAX responses with Cache-Control: no-cache, but with no effect.
Firefox 12 works OK.
I came with a workaround - I perform AJAX request with additional dummy GET parameter - ?ajax=1. This way the browser can recognize the difference between usual HTML content and JSON. It doesn't have any impact on the user, the parameter is visible only in Firebug.
I am having an issue with IE8 and its caching behaviour.
If I hit the page index.html and then continue to hit it again I am servered a page from the server.
However if I hit the page index.html?ui=v2 then index.html then index.html?ui=v2 I am served the page from cache.
The problem is the querystring ui=v2 is used to set a cookie which dtermines the view to deliver. As the page comes from cache the cookies view mode is not updated and I am served the same content as displayed for index.html (with no querystring).
This is IE8 and below, no other browsers.
Keen for any input Ideally I do not want to update the meta or response headers.
Thanks in advancecokkies
Browser: Firefox 6.0
I've Page A with the following setup to make sure the content is NOT stored in the bfcache of the browser:
1) $(window).unload(function(){});
2) Following HTTP headers:
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="expires" content="-1" />
<meta http-equiv="cache-control" content="no-cache"/>
I've also hooked up the events pagehide and pageshow. When I am navigating away from the page, pagehide is invoked with CORRECT value for the event property persisted = false (that is what needed: no persistence in cache!)
After navigating a couple of pages, I've a window.history.go(-2); to go back to Page A. At this point, I want Firefox to poll the server for the updated version instead of displaying from the cache. The pageshow of Page A is invoked with CORRECT value for the event propertypersisted = false (meaning the page is NOT loaded from cache). BUT the page content is not the server data; it is the stale content (same as when navigating away from the page initially)! Fiddler also does not show a new request to server.
Google Chrome also exhibits the same behaviour. IE works as expected (reloads fresh data)!
Any idea what am i missing?
Thanks in advance!
There are multiple caches involved. There's the browser's document cache (bfache), the browser's HTTP cache, and possibly intermediate HTTP caches.
The <meta> tags you show above have absolutely no effect in current Chrome or Firefox. They may have an effect in IE.
So chances are, your page is just being read from the browser's HTTP cache.
If you really want to send no-cache HTTP headers, you should do that. But they need to be actual HTTP headers: as I said above, the <meta> tag "equivalents" do nothing.
And, importantly, any other intermediate caches are not going to be parsing your HTML so might cache things if you don't actually send the right HTTP headers.
If you set Cache-Control: "no-cache, no-store, must-revalidate" to http headers the page won't be cached in back-forward cache.
Firefox also considers event handlers on beforeunload event as a signal to not store page in BFC, but Safari ignores such handlers, so it's better to set correct http headers to indicate the nature of the page content (cacheable or variable)
There are two caches to bear in mind:
The bfcache (back-forwards cache)
The bfcache (in Firefox, Safari and Chrome) stores the page in memory, including any dynamic modifications to the DOM. It is used by Firefox, Safari and Chrome when pressing back. To attempt to ensure that the page is not stored in this cache, you need to run these lines:
window.addEventListener('unload', function(){});
window.addEventListener('beforeunload', function(){});
Note that this seems to work in desktop Firefox and Chrome, but doesn't always work in desktop Safari, or Android Chrome or Android Firefox or iOS Safari.
Note that Webkit documentation calls the bfcache the "Page Cache".
The normal browser cache
Pages are cached in the normal browser cache, unless you set the proper no-store value in the Cache-Control heading. To be extra sure, send this full header:
Cache-Control: max-age=0, no-cache, no-store, must-revalidate, private
Firefox, Safari and Chrome will first check the bfcache when pressing the back button. They will then fall back to the normal cache. So you need to both add an event listener to unload, and set this Cache-Control HTTP header. Note that using <meta> instead of the HTTP header may not work.
References:
Article on back/forward cache by Chrome Developer Relations
The answer below does not work any more:
From answer on SO, adding an unload event to window causes the back/forward cache to be cleared.
UPDATE. POSSIBLE SOLUTION:
BFCache can bring surprises to developers, because at least in Firefox when moving back/forward the page does not refresh even if it was told by HTTP headers. So it's better to assume that the page will not refresh.
On the other hand, what is the difference between getting page with outdated data because of BFCache, and finding a tab in your browser that you did not reload for ages?
If you care about those kind of things, write some javascript that checks server for updates and reloads sensitive information. This is a chance to turn your problem into win ).
I have a page that gathers environment status from a couple of IBM WebSphere servers using iframes similar to this:
<iframe src="http://server:9060/ibm/console/status?text=true&type=server&node=NODE&name=ServerName_server_NODE"></iframe>
and it happily prints out "Started" or "Unavailable" etc. But if I load the same url in a normal browser sometimes it works, sometimes it does not? Some of them are showing a login page, while others are simply return HTTP code 500.
So whats the difference between loading the page through an iframe vs through a browser?
I can tell you that the iframe solution works no matter which machine I am doing it on, so I do not belive it has anything to do with the user whos opening the page. And before you ask, why not keep the solution that works, well its because it takes a long time to open the page with the iframes vs a page where everything is requested through ajax.
Update: Using jQuery to perform the ajax call returns "error" and "undefined" for the servers that I can't see in a normal browser.
One difference is an iframe has to render the view while XHR would not.
An iframe is essentially the same as opening with the browser. In both cases the browsers credentials are used, so there will be no difference between the two.
Secondly, loading something in an iframe should take the same amount of time as requesting it through XHR, since in both cases the browser makes an HTTP request and waits for the response. Although I should add that an iframe will take time to render the content onto the page. However if you plan on displaying it with ajax anyways, an iframe/xhr solution will be more or less the same.
In case of ajax request same origin policy (which restricts cross domain call) comes into picture. So you can't make cross domain call using xhr. Alternative for same is embed flex swf file in your page as activex control and make flex call through javascript and then flex is responsible to make cross domain call (flex can if targeted domain allows cross domain using crossdomain.xml) and renders result using javascript again.