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.
Related
I'm working on an HTML/javascript app intended to be run locally.
When dealing with img tags, it is possible to set the src attribute to a file name with a relative path and thereby quickly and easily load an image from the app's directory. I would like to use a similar method to retrieve a text file from the app's directory.
I have used TideSDK, but it is less lightweight. And I am aware of HTTP requests, but if I remember correctly only Firefox has taken kindly to my use of this for local file access (although accessing local images with src does not appear to be an issue). I am also aware of the FileReader object; however, my interface requires that I load a file based on the file name and not based on a file-browser selection as with <input type="file">.
Is there some way of accomplishing this type of file access, or am I stuck with the methods mentioned above?
The browser will not permit you to access files like that but you can make javascript files instead of text files like this:
text1.js:
document.write('This is the text I want to show in here.'); //this is the content of the javascript file
Now call it anywhere you like:
<script type="text/javascript" src="text1.js"></script>
There are too many security issues (restrictions) within browsers making many local web-apps impossible to implement so my solution to a similar problem was to move out of browsers and into node-webkit which combines Chromium + Node.js + your scripts, into an executable with full disk I/O.
http://nwjs.io/
[edit] I'm sorry I thought you wanted to do this with TideSDK, I'll let my answer in case you want to give another try to TideSDK [/edit]
I'm not sure if it's what you're looking for but I will try to explain my case.
I've an application which allow the user to save the state of his progress. To do this, I allow him to select a folder, enter a filename and write this file. When the user open the app, he can open the saved file, and get back his progress. So I assume this enhancement is similar of what you are looking for.
In my case, I use the native File Select to allow the user to select a specific save (I'm using CoffeeScript) :
Ti.UI.currentWindow.openFileChooserDialog(_fileSelected, {
title: 'Select a file'
path: Ti.Filesystem.getDocumentsDirectory().nativePath()
multiple: false
})
(related doc http://tidesdk.multipart.net/docs/user-dev/generated/#!/api/Ti.UI.UserWindow-method-openFileChooserDialog)
When this step is done I will open the selected file :
if !filePath?
fileToLoad = Ti.Filesystem.getFile(scope.fileSelected.nativePath())
else
fileToLoad = Ti.Filesystem.getFile(filePath)
data = Ti.JSON.parse(fileToLoad.read())
(related doc http://tidesdk.multipart.net/docs/user-dev/generated/#!/api/Ti.Filesystem)
Please note that those snippets are copy/paste from my project and they will not work without the rest of my code but I think it's enough to illustrate you how I manage to open a file, and read his content.
In this case I'm using Ti.JSON.parse because there is only javascript object in these files but in your case you can just get the content. The openFileChooserDialog isn't mandatory, if you already know the file name, or if you get it from another way you can use Ti.Filesystem in your own way.
I have a question about html and javascript. I'm trying to find out if we can generate html files from javascript.
I want to implement a dynamic form in which a user makes choices like entering a question and answer. At the end, I would have an html file in which I have a form with the user's choices.
With Javascript, I know that I can create a dynamic form but is it possible to write it to a file?
If you don't care about older browsers you can take a look at this article http://www.html5rocks.com/en/tutorials/file/filesystem/
You can try and store the content you need in a session or cookie or even local storage for a more wide browser support.
As mentioned in the article:
At the time of writing this article, Google Chrome has the only working implementation of the FileSystem API.
You can also add a server side API that will listen to your javascript and create the files (if you want the files to be stored on your server). For this you can check some implementations like http://extplorer.sourceforge.net/
Hope this helps.
Yes, here you have an example:
var html = '<!DOCTYPE html>'
+'<html>'
+'<head>'
+'<title>Title</title>'
+'</head>'
+'<body>'
+'<p>Content</p>'
+'</body>'
+'</html>',
params = 'data:text/html;charset=UTF-8';
if(window.btoa){
params += ';base64';
html = window.btoa(unescape(html));
}
window.open(params + ',' + html);
If you run this code you will generate an html file and open it using data URIs!
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 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
This sounds like a trivia question but I really need to know.
If you put the URL of an HTML file in the Location bar of your browser, it will render that HTML. That's the whole purpose of a browser.
If you give it a JPG, or a SWF, or even PDF, it will do the right things for those datatypes.
But, if you give it the URL of a JavaScript file, it will display the text of that file. What I want is for that file to be executed directly.
Now, I know that if you use the javascript: protocol, it will execute the text of the URL, but that isn't what I need.
I could have the URL point to an HTML file consisting of a single <script> tag that in turn points to the JavaScript file, but for occult reasons of my own, I cannot do that.
If the file at http://example.com/file.js consists entirely of
alert("it ran");
And I put that URL in the Location bar, I want "it ran" to pop up as an alert.
I'm skeptical that this is possible but I'm hoping-against-hope that there is a header or a MIME type or something like that that I can set and miraculously make this happen.
This is not possible. The browser has no idea what context the JavaScript should run in; for example, what are the properties of window? If you assume it can come up with some random defaults, what about the behavior of document? If someone does document.body.innerHTML = "foo" what should happen?
JavaScript, unlike images or HTML pages, is dependent on a context in which it runs. That context could be a HTML page, or it could be a Node server environment, or it could even be Windows Scripting Host. But if you just navigate to a URL, the browser has no idea what context it should run the script in.
As a workaround, perhaps use about:blank as a host page. Then you can insert the script into the document, giving it the appropriate execution context, by pasting the following in your URL bar:
javascript:(function () { var el = document.createElement("script"); el.src = "PUT_URL_HERE"; document.body.appendChild(el); })();
Or you can use RunJS: https://github.com/Dharmoslap/RunJS
Then you will be able to run .js files just with drag&drop.
Not directly, but you could make a simple server-side script, e.g. in PHP. Instead of
http://example.com/file.js
, navigate to:
http://localhost/execute_script.php?url=http://example.com/file.js
Of course, you could smallen this by using RewriteRule in Apache, and/or adding another entry in your hosts file that redirects to 127.0.0.1.
Note that this is not great in terms of security, but if you use it yourself and know what you're downloading, you should be fine.
<html>
<head>
<script>
<? echo file_get_contents($_GET['url']); ?>
</script>
</head>
<body>
</body>
</html>
In the address bar, you simply write
javascript:/some javascript code here/;void(0);
http://www.javascriptkata.com/2007/05/01/execute-javascript-code-directly-in-your-browser/
Use Node.js.
Download and install node.js and create a http/s server and write down what you want to display in browser.
use localhost::portNumber on server as url to run your file.
refer to node js doc - https://nodejs.org/dist/latest-v7.x/docs/api/http.html
Run - http://localhost:3000
sample code below :
var http = require("http");
var server = http.createServer(function(req,res){
res.writeHead(200,{'Content-Type':'text/html'});
res.end("hello user");
}); server.listen(3000);`
you can write your own browser using qt /webkit and do that.
when user enters a js file in url location you can read that file and execute the javascript .
http://code.google.com/apis/v8/get_started.html is another channel.
not sure if it meets ur need.