How can I create a JavaScript button that downloads a html page wich is put into a string.
So that people can download a page for offline viewing.
So I have this string (Just a small sample):
var DownloadHtml="<html><head><title>Test</title></head><body><p>Test</p></body></html>";
And I want to be able to let the user download that HTML page.
Edit on an attempt to make it more clear:
I would prefer something downloadable so the user has it on his desktop. It's not really an offline version of the page itself, it's a timelist of taggings in a video service, the tags are shown in a list while watching, but you could also download it to see who commented when and by clicking on one of the comments you open the video on the time the person had commented
as an answer:
<script src="http://danml.com/js/download.js">
<script>
var DownloadHtml="<html><head><title>Test</title></head><body><p>Test</p></body></html>";
download(DownloadHtml, "saved.html", "text/html");
</script>
note that if you want to support old browsers, you'll need to echo it off of a server and attach a content-disposition header.
You need to use cache and <html manifest=...>
It allows you to define, what are the elements to be shown while the user is viewing offline.
Read more:
http://www.w3schools.com/tags/att_html_manifest.asp
http://www.w3schools.com/html/html5_app_cache.asp
Related
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.
I am trying to capture some content of a div in html (both text and images) and I want to convert that to a doc file so that i can mail it. I am using html5 javascript and jQuery.
I have to convert it on the client side.
Here's your solution http://www.phpdocx.com/. You'll need a server side language to do that, the example uses PHP.
Since you have such strict requirements:
Email the user a link with a version of the report you want the user to see when they open the doc.
Tell the user to open MS Word, Click File, Open, Then paste the link in.
The user can then save it as a .doc file where ever they want.
Note: By the way this is the wrong answer, Although you've already turned it down, slash197's answer is the correct way to do this and the way i would normally suggest.
That or just email the report as html.
I am aware of the hidden iFrame trick as mentioned here (http://stackoverflow.com/questions/365777/starting-file-download-with-javascript) and in other answers.
I am interested in a similar problem:
How can I use Javascript to download the current page (IE: the current DOM, or some sub-set of it) as a file?
I have a web page which fetches results from a non-deterministic query (eg. a random sample) to display to the user. I can already, via a querystring parameter, make the page return a file instead of rendering the page. I can add a "Get file version" button (our standard approach) but the results will be different to those displayed because it is a different run of the query.
Is there any way via Javascript to download the current page as a file, or is copying to the clipboard my only option?
EDIT
An option suggested by Stefan Kendall and dj_segfault is to write the result server side for later retrieval. Good idea, but unfortunately writing files server side is out of the question in this instance.
How about shudder passing the innerHTML as a post parameter to another page?
You can try with the protocol data:text/attachment
Like in:
<html>
<head>
<style>
</style>
</head>
<body>
<div id="hello">
<span>world</span>
</div>
<script>
(function(){
document.location =
'data:text/attachment;,' + //here is the trick
document.getElementById('hello').innerHTML;
//document.documentElement.innerHTML; //To Download Entire Html Source
})();
</script>
</body>
</html>
Edit after shesek comment
To add to Mic's terrific answer above, some additional points:
If you have Unicode content (Or want to preserve indentation in the source), you need to convert the string to Base64 and tell the Data URI to treat the data as such:
(function(){
document.location =
'data:text/attachment;base64,' + // Notice the new "base64" bit!
utf8_to_b64(document.getElementById('hello').innerHTML);
//utf8_to_b64(document.documentElement.innerHTML); //To Download Entire Html Source
})();
function utf8_to_b64( str ) {
return window.btoa(unescape(encodeURIComponent( str )));
}
utf_to_b64() via MDN -- works in Chrome/FF.
You can drop this all into an anchor tag, allowing you to set the download attribute:
<a onclick="$(this).attr('href', 'data:text/plain;base64,' + utf8_to_b64($('html').clone().find('#generate').remove().end()[0].outerHTML));" download="index.html" id="generate">Generate static</a>
This will download the current page's HTML as index.html and removes the link used to generate the output. This assumes the utf8_to_b64() function from above is defined somewhere else.
Some useful links on Data URIs:
MDN article
MSDN article
Depending on the size and if support is needed for ancient browsers, but you can consider creating a dynamic file using data: URIs and link to it. I'be seen several places that do that. To get the brorwser to download rather than display it, play around with the content type you put in the URI and use the new html5 download attribute. (Sorry for any typos, I'm writing from my phone)
I don't think you're going to be able to do it exactly the way you want to. JavaScript can't create a file and download it for security reasons. Nor can it create it on the server for download.
What I would do if I were you is, on the server side, create an output file with the session ID in the name in a temp directory as you create the output for the web page, and have a button on the web page with a link to that file.
You'll probably want a separate process to remove files over a day old or something like that.
Can you not cache the query results, and store it by some key? That way you can reference the same report output forever, or until your file garbage collector comes along. This also implies that you can create static URLs to report outputs, which tends to be nice.
Let's look at FireFox.
They have a nice big Call To Action button: "Firefox 3.6 - Free Download"
You click that, it links you to a new page: "Thanks for downloading Firefox! Your download should begin in a few seconds."
Then a few seconds later up pops: "FIREFOX.exe - Do you want to save or discard this file?"
This is pretty standard download behavior for applications accross the web. How is it done, in the simplest way?
There are two parts to this:
Forcing the browser to download the file, rather than trying to display it (with .exe that's no problem, but you might want to do it with an image, movie, or HTML file too).
Prompting the browser to download the file.
Let's pretend we just want the browser to download a file, without wanting to change the page. We can create a link like this, and it'll work as expected:
Download File
Your browser probably doesn't know how to handle a zip file, so it downloads "download.zip" straight to a file named after the filename in the URL. If you wanted to download a JPG instead, though, this wouldn't work:
Save this Sunset!
Your browser knows how to display a JPEG, so it redirects the page and shows the JPEG. Now we need to tell the browser not to show it, but to download it instead. To do that, we have to send it some specific HTTP headers in the response from the server.
Apache can handle this by specifying headers in .htaccess, but I'll stay away from a particular technology, opting to just talk about the mechanism.
So we send the following header to the browser along with the image:
Content-disposition: attachment; filename=the_sunset_of_a_lifetime.jpg;
The first header, content-disposition, tells your browser that we want the file to be an attachment, or in other words, it should be saved, not displayed. The filename attribute tells it the name to use to save the file (rather than "sunset.jpg", the file will be named "the_sunset_of_a_lifetime.jpg").
Now the link to download the "sunset.jpg" file works like we want. But how do we get the browser to download it without the user clicking on the link so we can show a "Thank You" page and prompt the download to start? A simple <meta> tag can do the trick, telling the browser to redirect the page after a set period of time:
<meta http-equiv="refresh" content="2;url=/images/sunset.jpg">
When your "thank you" page loads with that meta tag in the head, it'll wait for 2 seconds and then try to load the image. It'll get the headers we set in the last step, and download it instead of displaying it, and the user will stay put on the page like we want.
Example content of thanks_for_downloading.html:
<strong>Thanks for downloading XY</strong>
<script type="text/javascript">
window.onload = function(){
window.location.href = "path/to/XY.exe";
};
</script>
The Download-link is just a link to the thanks_for_downloading.html page
The call to action button is a regular link to the "Thank you" page. Then on the "Thank you" page, use javascript to redirect the user to the file you are downloading by setting the "window.location" property to the file's URL.
Currently some guys programmed this in a HTML page:
<script>
location='http://example.com/downloadable.zip';
</script>
They want to redirect the user to another page once the file has started downloading. I can only modify this page but not the destination page.
What would be a good and clean javascript solution for making a user download the file and once he had accepted (or rejected) it, redirect him to another location? The solution may be jQuery code
NOTE: The downloading and redirection must be done automatically when accessing the page
Perhaps setup a link that calls a function. The function would in turn then send the download link, and then redirect.
This is just a guess based upon your description, as I don't know the full general setup, but it's what I would do going on what I know.
This seems like a hack. Have you tried an HTML meta tag with refresh? Also, you can add a link if the download fails.