How do I prevent caching on a website? - javascript

Within a website in development, we have it templated as a master page that contains the head of the webpage, then a header and body div that loads in content dynamically. Basically, I'm trying to prevent caching on all the pages loaded in dynamically.
Browsers would be IE8 onwards.

As you said you should only be doing that if the website is in development or the content really needs to be loaded fresh every time. Internet Explorer supports some meta tags that can do what you need, specifically
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="-1">
Click here for more information
If you ever want to test in firefox, you could try out this plugin

If you are using Google Chrome to develop, there are an option that let you cache free when dev tools is open, but if you want a simple trick is just to pass a timestamp in a query string during your request. Something like:
http://localhost/path/to/project/?nocache=74567363
If you are using some framework that helps you to handle with the includes like AngularJS ou BackboneJS, make the redirects with:
var myUrl = 'http://localhost/path/to/project/?nocache=';
var timestamp = (new Date()).getTime();
window.location.href = myUrl + timestamp;

Related

Cache is not cleared in Google Chrome

When I deploy the version I will add the number as a query string with the JavaScript and CSS file like following?
'app/source/scripts/project.js?burst=32472938'
I am using the above to burst the cache in the browser.
But in Firefox, I am getting the latest script that I have modified.
But in Chrome, I am not getting the latest script that I have modified. Instead of that, I am getting the old one.
But in the developer console, I am seeing the burst number which is modified in latest.
According to the Google documentation, the best way to invalidate and reload the file is to add a version number to the file name and not as a query parameter:
'app/source/scripts/project.32472938.js'
Here is a link to the documentation:
https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching#invalidating_and_updating_cached_responses
Another way is to use an ETag (validation token):
https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching#validating_cached_responses_with_etags
Here is how you would set up an ETag with Nginx:
http://nginx.org/en/docs/http/ngx_http_core_module.html#etag
And lastly, a tutorial about browser caching with Nginx and ETag:
https://www.digitalocean.com/community/tutorials/how-to-implement-browser-caching-with-nginx-s-header-module-on-centos-7#step-2-%14-checking-the-default-behavior
I'm uncertain of whether this still applies these days, but there were some cases in the past where proxies could cause a query-string value to be ignored for caching purposes. There's an article from 2008 that discussed the idea that query-string values weren't ideal for the purpose of breaking caching, and that it was better to revise the filename itself -- so, referencing project_32472938.js instead of using the query-string.
(I've also seen, in places, some discussion of unusual cases where certain clients were not seeing these updates, but it seemed to be inconsistent -- not tied to Chrome, necessarily, but more likely tied to a specific installation of Chrome on a specific machine. I'd certainly recommend checking the site on another computer to see if the issue is repeated there, as you could at least narrow down to whether it's Chrome in general, or your specific install of Chrome that is having problems.)
All that said, it's been quite a while since 2008, and that may not be applicable these days. However, if it continues to be a problem -- and you can't find a solution to the underlying problem -- it at least offers a method use to circumvent it.
I don't think that Chrome actually causes the problem, because
it would break almost all web applications
(eg: https://www.google.com/search?q=needle)
It could be that your deployment was a bit delayed, eg.
Start install new scripts
Check with Chrome (receives old version on new ID)
Install finishes
You try with Firefox (receives new version)
Chrome still shows old version because it cached the old script with new ID
Or you have a CDN like Azure between your web server and your browser.
With standard settings Azure CDN ignores the query string for the caching hash.
try those meta tags:
<meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="expires" content="0" />
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
<meta http-equiv="pragma" content="no-cache" />
i not sure , but for try...
google crome always ignore it..
you need to add a '?random.number' or "?date.code" to every link each time a url is pressed on your website.
eg if 'myhomepage.html?272772' is stored in the cache, then by generating a new random number eg 'myhomepage.html?2474789', google chrome will be forced to look for a new copy.

Is there a solution to correctly open user authenticated URL from Microsoft Office programs?

The scenario I'm going to describe is about Excel, but you can spot the same problem in all Office tools.
Scenario:
In my default browser (NOT Internet Explorer) I'm logged in my own specific website, let's call it www.mypersonalwebsite.com
I have an Excel folder with the A1 cell containing a URL pointing to http://www.mypersonalwebsite.com/url/visible/only/to/loggedin/users
When I click on the URL in A1 cell:
my default browser is trying to open this URL
the website is refusing to serve the page because the request is coming from a non logged in user
So that's the problem: why is the browser complaining about the user session when I'm already logged in? And how can I solve it?
I found many similar questions about this problem on stackoverflow and I think I composed a portable and "definitive" solution to this problem.
First of all: why is the browser complaining about the user session?
The answer is "Microsoft Office Protocol Discovery". In a few words: it's something that works only if you are using Microsoft Windows and your default browser is Internet Explorer.
Basically, if you are not using Microsoft Windows OR your default browser is not Internet Explorer, when you click on an URL, the request sent to the browser will always be with an empty cookie. This means that, despite the default browser could use a correct cookie to authenticate the user, the request coming from Excel will never use it. But if you try to reload the page (and the webserver is not redirecting to a different error page), the browser will use the domain cookie and you'll see the correct page.
Second question: how can I solve this problem?
I think I found a very good solution, composed by an HTML part and a webserver part.
HTML part
Starting from the fact that you need to reload the page to use the cookie, I created a simple static page containing a little javascript code and some html. This is just an example. The main part of this code is here.
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<script type='text/javascript'>
function getParameterByName(name) {
var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}
</script>
<meta charset="UTF-8">
<script type="text/javascript">
window.location.href = getParameterByName('newUrl');
</script>
<title>Page Redirection</title>
</head>
<body>
<!-- Note: don't tell people to `click` the link, just tell them that it is a link. -->
If you are not redirected automatically, follow the <a href='<?php echo $newUrl; ?>'>link</a>
</body>
</html>
You can access to the querystring via javascript in many ways, you can find a very interesting thread here.
This static page, let's call it redirect.html, will only do one thing: it will redirect the browser to the page specified in the newUrl parameter. Now if I put in the A1 cell something like:
http://www.mypersonalwebsite.com/redirect.html?newUrl=http://www.mypersonalwebsite.com/url/visible/only/to/loggedin/users
and if I click on this URL:
Excel will go to this URL using the default browser
The browser will open the redirect.html page with an empty cookie
The browser will reload the page using the domain cookie
The user will see the correct page as an authenticated user
The pros of this trick are: it works on all platforms and on all browsers supporting javascript. The cons are that we need to modify all URLs in all our Excel folders.
 The webserver part
To hide this redirection to the end users, and save us to modify all our Office documents, we can use another trick. In this example I will use nginx:
if ($http_user_agent ~* "(Excel|PowerPoint|Microsoft Office)") {
rewrite ^/(.*)$ /redirect.html?url=$1 break;
}
The meaning of this little if block is: if the incoming request is from a user agent like Excel, Powerpoint and so on, nginx will do an internal redirection to the redirect.html page, that will again do the browser redirection explained above.
This nginx redirect will completely hide the redirect trick, so we can use the original URLs and the users will always see the correct page.
I'm sure all this can be improved, and I would like to learn how to do it.
I hope this will help someone in finding a complete solution to this Office problem.

Force Internet Explorer to ignore IE=EmulateIE8

I'm working with Blackboard 9.1 SP13 and by the default the platform has the typical:
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />
But i want Internet Explorer >8 to ignore this meta tag in just one page because it is not working properly.
I can't change the meta tag since it is hardcoded in the platform and I can't customize this feature (my boss doesn't allow me to change de .vm template, it is not an option).
¿Is there a way I can tell Internet Explorr >8 to ignore this meta in the page with a code inside the page? Some kind of Javascript or something...
Thanks in advance
Try having the server send the equivalent header with a new value:
X-UA-Compatible: IE=edge
In general, headers from the server override headers set in HTML.

I need to add meta headers to URLRequest in flex3

I am writing a flex3 tool for our uber-geeks. The tool is for futzing around with sharing URLs to various various social sites.
private function submitRequest(evt:Event):void {
var requestURL:URLRequest = new URLRequest(constructURL());
requestURL.method=URLRequestMethod.POST;
var header:URLRequestHeader = new URLRequestHeader("og:title", "petertitle");
requestURL.requestHeaders.push(header);
navigateToURL(requestURL,"_blank");
}
I want allow the developer to manipulate the following meta headers in the outgoing html request when navigateToURL() is called.
<meta property="og:title" content=title" />
<meta property="og:description" content="description" />\
<meta property="og:image" content="......" />
<meta property="og:video" content="......"/>
<meta property="og:video:height" content="640" />
<meta property="og:video:width" content="480" />
Unfortunately google is not showing me any example of how to add the above meta headers to my instance of URLRequest in flex. AND the new URLRequestHeader is blowing up.
ArgumentError: Error #2096: The HTTP request header og:title cannot be set via ActionScript.
at global/flash.net::navigateToURL()
Can someone point me at an example of putting the meta headers into a URLRequest?
additional
Looks like I am in a catch 22 situation.
I wrote the app to run in a flash player.
apparently the flash apps run from flashbuilder are not permitted to perfom http PUT method operations. it alwasy does GET
flash apps run from flashbuilder will not write headers on http GET calls.
But I am still not finding a way to add an http "meta" header tag in flex... perhaps adobe air.
Current work around.
I can call an external javascript function that will do a post, but however the XmlHttpRequest infrastructure only want to setRequestHeader(key,value), and seems to need to be from a very specific list of strings. setRequestHeader("foo","bar") did not add a foo header in my outgoing request.
There does not seem to be a way to add the header meta tag. via javascript. Or at lease I am not finding it off of google.
Hoping someone can now point me at how to do that?????
Do either of these help (appears the first one is particularly relevant, otherwise in the second a work-around is offered):
How can i send custom headers with URLRequest
Custom headers possible with URLRequest/URLStream using method GET?
What a pain. I would have thought someone would have run into this before and posted such a solution
setRequestHeader(arg1, arg2) ouptputs "< arg1 arg2 />" in the outgoing http request
so if I
xmlhttp.setRequestHeader("meta","property=\"og:description\" content=\"description\"");
then the outing html
<head>
....
<meta property="og:description" content="description"/>
....
</head>
<body>
....
</body>

How may I disable an http-equiv refresh in JavaScript?

I'm building a status page which should be refreshed periodically.
So, I've had a http-equiv refresh in the <head> section in order to refresh the page every minute :
<meta http-equiv="Refresh" id="refresh" content="60"/>
But, for browser supporting JavaScript, I would like to send an Ajax request checking if the page should be refreshed or not. And so, I would like to disable that http-equiv refresh in JavaScript (because it's Ajax which will do the work).
I tried to remove the tag using JavaScript/PrototypeJs but that doesn't work :
$('refresh').remove();
It seems that the browser keep trace of that timer and doesn't take care of that DOM update.
Any idea ?
Not exactly sure, but maybe:
<noscript>
<meta http-equiv="Refresh" id="refresh" content="60"/>
</noscript>
This would be better handled on the server. There are a number of tools to let you reliably check to see if the browser supports JS (BrowserHawk is one that comes to mind) or you can check the SupportsECMAScript (in ASP.NET) property of the Browser object and write out different code if the browser supports JS.
I don't think there's a way of disabling the http-equiv refresh.
Is the status page the first page in your app? If not, then why not get the capabilities of the client up front before requesting the status page? If it is then you might have to inject a UI-less page that grabs the capability of the browser and instantly post back to the real status page. All this assumes that you're not willing to use the user agent string in the HTTP Header to get the browser capability.

Categories

Resources