Prevent html pages from browsing caching - javascript

The problem I am having is partial files(*.html) are getting cached by browser. While developing it's not a big problem but once I deploy the application, clients see the old page(s) until they clear their cache or hit ctrl F5
I have tried specifying meta tags(CACHE-CONTROL,EXPIRES) but still see those pages getting picked up
from cache in the developer tool of chrome (Maybe I am missing something here?).
I was going to try and add some random number in front of the url like
<div ng-include src="'views/test.html?i=1000'"></div>
But came across https://groups.google.com/forum/#!topic/angular/9gORRowzP2M ,where James cook rightly states that this way would fill cache with partials over and over.
I read somewhere that it's better to set the meta tags in headers from the server but I don't know how to do that? I was thinking of somehow doing it in an http interceptor?Maybe somehow add meta tags in request or response of this httpinterceptor? https://gist.github.com/gnomeontherun/5678505
Any ideas how to do that? Or if it's good/bad idea? Or any other way to prevent partial pages getting cached by browser?

To prevent caching it is in many circumstances not possible to completely turn it off from the client side only. You have to configure your server in the right way so that it produces the right HTTP-Headers.
But with the help of $templateCache you can move your html partials form single files into script tags in your index.html file. This will also reduce the number of AJAX calls your app needs to make.
With the templates in your index.html you only need to make sure that the index.html is not getting cached.
Here is also a discussion of it:
Is there a way to make AngularJS load partials in the beginning and not at when needed?

In case anyone else run into the same problem, I ended up adding an httphandler and added the "Cache-Control" and "Expires" in the response header
public void ProcessRequest(HttpContext context)
{
var partial = context.Request.FilePath;
var filepath = context.Server.MapPath("~/" + partial);
context.Response.AddHeader("Content-Disposition", "filename=\"" + Path.GetFileName(filepath) + "\"");
// To make sure partial html pages are not cached by browser(s)
context.Response.AddHeader("Cache-Control", "No-Cache");
context.Response.AddHeader("Expires", "0");
context.Response.ContentType = MimeTypesHelper.GetMimeType(filepath);
context.Response.WriteFile(filepath);
}

Related

Reload from server for all files

I know it's possible to force reload from server using location.reload(true). However, let's say I used that to refresh index.html. If index.html loads a bunch of javascript files, those are still coming from the cache for me. Is there any way to ignore the cache for the duration of a request?
My use case is that I'm doing AB testing on my app, and want to provide a way for users to go back to the old version if something isn't working. But some of the URLs are the same, even though the files between versions are different. It would be nice to be able to handle this in JS rather than having to change every URL on the new version.
There is actually at least 535 different ways to reload a page via javascript, FYI ;).
Have you tried to put document on front? document.location.reload(true);
Try also this other option:
window.location.href = window.location.href;
or
history.go(0);
Sure, both are soft reload, but seems to work in certain situation.
If nothing works, you have to append random data to the url (like timestamp) to force the download from server, bypassing the cache.
If you want to bypass browser taking js files from cache, you need to fetch from server not just files like script.js but rather script.12345.js When you update your file on server, you change file's hash number to let's say script.54321.js And browser understands that the file is different, it must download it again. You can actually use Webpack for this purpose to automate things. In output instead of {filename: bundle.js} you write {filename: bundle.[hash].js}

Redirect from file based on referrer using JavaScript

Versions of this question have been posted numerous times, but none of the solutions I've found on this site have worked so far. I'm trying to redirect away from files, not web pages. I actually need to know if this is even possible, since I learned that PHP is incapable of doing this. Here's an answer from a previous question I asked:
The web server will first check if it exists and if it does, it will serve the file immediately. It does not go through any PHP code. Therefore you cannot write any PHP code that will intercept this request and block it.
We have a folder on our site with a path of /downloads/, containing files we don't want just anyone to download.
I want to put a script in our main JavaScript file that says:
If file is is /downloads/
If user comes from referrer allowed_domain.com, allow access to files in /downloads/
Else redirect to homepage or 404
My attempt (didn't work)
if (top.location.pathname === '/downloads/private.zip') {
if (document.referrer !== "http://www.allowed_domain.com") {
document.location.path = "/downloads/private.zip";
}
else {
document.location.path = "/404";
}
}
Constraints
I cannot use .htaccess. Our hosting provider is running Nginx, not Apache. I've tried using Nginx config code, but I have to send it to them to implement, and it didn't work and they won't help me.
And yes, I know that this is a super, super insecure solution for restricting access. My company is working on a more formal solution, but until then, I need to implement something temporary to deter users who lack the computer knowledge or motivation to get around the redirect, and this is pretty much my last option.
This problem is not solvable in JavaScript, even in the very limited and insecure way that you are proposing. The problem is that a request to /downloads/private.zip directly returns the contents of that file - it doesn't load any HTML page, so the browser will never see or execute that JavaScript code.
A way to solve this would be to have a PHP file that handles any request to that directory, checks whether the user has permission to see those files, and then returns the requested file or a 404. But for that you need some form of configuration, and you've already told us you can't do that either.
A third solution, one that is very silly but would work (for unsavvy users) in this very constrained situation would be to replace all links to the forbidden resources with a snippet of JavaScript that directs the user either to the file or a 404 page. However, from your question it seems very likely that you're trying to prevent access from users coming from sites outside of your control, in which case this won't work either.
Bottom line: This is not a solvable problem if you don't have the ability to configure your web server.

How can I *locally* save an .html file generated by javascript (running on a *local* .html page)?

So I've been researching this for a couple days and haven't come up with anything conclusive. I'm trying to create a (very) rudimentary liveblogging setup because I don't want to pay for something like CoverItLive. My process is: Local HTML file > Cloud storage (Dropbox/Drive/etc) > iframe on content page. All that works, and with some CSS even looks pretty nice despite the less-than-awesome approach. But here's the thing: the liveblog itself is made up of an HTML table, and I have to manually copy/paste the code for a new row, fill in the timestamp, write the new message, and save the document (which then syncs with the cloud and shows up in the iframe). To simplify the process I've made another HTML file which I intend to run locally and use to add entries to the table automatically. At the moment it's just a bunch of input boxes and some javascript to automate the timestamp and write the table row from the input data.
Code, as it stands now: http://jsfiddle.net/LukeLC/999bH/
What I'm looking to do from here is find a way to somehow export the generated table data to another .html file on my hard drive. So far I've managed to get this code...
if(document.documentElement && document.documentElement.innerHTML){
var a=document.getElementById("tblive").innerHTML;
a=a.replace(/</g,'<');
var w=window.open();
w.document.open();
w.document.write('<pre><tblive>\n'+a+'\n</tblive></pre>');
w.document.close();
}
}
...to open just the generated table code in a new window, and sure, I can save the source from there, but the whole point is to eliminate steps like that from the process.
How can I tell the page to save the generated code to a separate .html file when I click on the 'submit' button? Again, all of this happens locally, not on a server.
I'm not very good with javascript--and maybe a different language will be necessary--but any help is much appreciated.
I suppose you could do something like this:
var myHTMLDoc = "<html><head><title>mydoc</title></head><body>This is a test page</body></html>";
var uri = "data:application/octet-stream;base64,"+btoa(myHTMLDoc);
document.location = uri;
BTW, btoa might not be cross-browser, I think modern browsers all have it, but older versions of IE don't. AFAIK base64 isn't even needed. you might be able to get away with
var uri = "data:application/octet-stream,"+myHTMLDoc;
Drawbacks with this is that you can't set the filename when it gets saved
You cant do this with javascript but you can have a HTML5 link to open save dialogue:
<a href="pageToDownload.html" download>Download</a>
You could add some smarts to automate it on the processed page after the POST.
fiddle : http://jsfiddle.net/ghQ9M/
Simple answer, you can't.
JavaScript is restricted to perform such operations due to security reasons.
The best way to accomplish that, would be, to call a server page that would write
the new file on the server. Then from javascript perform a POST request to the
server page passing the data you want to write to the new file.
If you want the user to save the page to it's file system, this is a different
problem and the best approach to accomplish that, would be to, notify the user/ask him
to save the page, that page could be your new window like you are doing w.open().
Let me do some demonstration for you:
//assuming you know jquery or are willing to use it :)
var html = $("#tblive").html().replace(/</g, '<');
//generating your download button
$.post('generate_page.php', { content: html })
.done(function( data ) {
var filename = data;
//inject some html to allow user to navigate to the new page (example)
$('#tblive').parent().append(
'Check your Dynamic Page!');
// you data here, is the response from the server so you can return
// your new dynamic page file name here.
// and maybe to some window.location="new page";
});
On the server side, something like this:
<?php
if($_REQUEST["content"]){
$pagename = uniqid("page_", true) . '.html';
file_put_contents($pagename, $_REQUEST["content"]);
echo $pagename;
}
?>
Some notes, I haven't tested the example, but it works in theory.
I assume that with this the effort to implement it should be minimal, assuming this solves your problem.
A server based solution:
You'll need to set up a server (or your PC) to serve your HTML page with headers that tell your browser to download the page instead of processing the HTML markup. If you want to do this on your local machine, you can use software such as WAMP (or MAMP for Mac or LAMP for Linux) that is basically a web server in a .exe. It's a lot of hassle but it'll work.

How to save scripts, images and css files into browser cache?

I have been trying to enable Caching for my web-page. I find-out so much post related to Caching static file in browser cache, but i did't get success.
I try for both server side or client side code for it:
SERVER SIDE
I tried to put code for set-up a "Cache-Control" header on server side page-load(write code in C#) :
DateTime dt = DateTime.Now.AddMinutes(30);
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.Public);
HttpContext.Current.Response.Cache.SetExpires(dt);
HttpContext.Current.Response.Cache.SetMaxAge(new TimeSpan(dt.Ticks - DateTime.Now.Ticks));
Reference
CLIENT SIDE
In javascript after some googling i find a "Preloading images" technique , but applying this code also not give me correct solution of storing file into cache.
Reference
HTML META TAGS
Added following tags in my page header:
<meta http-equiv="Cache-control" content="private"/>
<meta http-equiv="EXPIRES" content="Wed, 16 oct 2013 11:12:01 GMT"/>
did't get success.
Reference
Can any one tell me what i am doing wrong here?
And any one suggest me for perfect solution/full tutorial for enabling cache to store static files into browser cache.
Thanks in advance....!!!!
First i think you have confused caching with preloading images.
If what you really need is caching, check your browser whether caching is disabled.Because scripts,images and css are cached defaultly by browser.
Next how did you check whether those are cached?
You could use "cache-manifest" which uses AppCache of the browser.
It allows you to run your website offline also.
Head to http://diveintohtml5.info/offline.html for more information.
Hope it helps!!

JavaScript = "js"? Is this valid?

I inherited a website, I'm trying to serve its content over https, but when I do so I get an error that this "content" is being delivered insecurely. The certificate and all that good stuff is set up correctly.
<script type="text/javascript" src="https://domain.com/?dynamic=js"></script>
This doesn't seem to actually reference a file. I've googled but can't find anything to lead me in the right direction. Can anyone provide some insight, or better yet explain why this leads to the security problem?
Yes, it is valid so long as https://domain.com/?dynamic=js generates a javascript file. See this page for more info on dynamic files:
http://www.dynamicdrive.com/forums/showthread.php?21617-Dynamic-external-js-scripts-and-css-stylesheets-with-PHP
If you are running under secure connection (https) then all the resources in your domain have to be also serving via https - like images etc...
check to see if some image is using http: and not https
There's no problem with the script-tag. You don't actually need a .js-extension for it to be valid, as long as it returns JavaScript the browser will be happy.
Also, this line has nothing to do with the HTTPS-error you're getting. You should make sure that ALL the content linked on that page is delivered through HTTPS
Make sure ALL of the assets on the page are served up with relative paths. Images. css. scripts, etc.. Then they will load no matter if you are on https or not.
Relative = "/images/test.jpg" instead of "http://test.com/images/test.jpg"
Also can do Protocol relative url : "//test.com/images/test.jpg" (Thanks to commenter)

Categories