Possible to generate text files in javascript?

K

kerinin

I'd like to be able to generate a text file in a web browser, then
supply a link which will allow users to save that file to disk. I'm
not trying to read from the local machine or even write directly to
the local machine, I'm simply trying to provide a file which the local
browser and save as it would any other URL.

Just to give some idea of my motivation, I'm working with encrypted
data which is decrypted locally (so the server never has access to the
data). I'd like to be able to save the cleartext in some cases as a
text file.

Thanks
-Ryan
 
P

Peter Michaux

User clicks a button.
Browser opens new window with text file.
User uses File>Save As to save the text file.

[snip]


Wouldn't the new window have HTML formatting as well as the text?

If the servers sends the file with a "Content-Type text/plain" header
then it will just show as text.

Peter
 
K

kerinin

If the servers sends the file with a "Content-Type text/plain" header
then it will just show as text.

Peter

The problem is that I don't want the server to have access to the data
- could the server send a blank document and then the client machine
could modify the text in it, or can the document.write functions only
operate on html Content-Types? Or alternately, could I open a new
window with javascript and specify a blank URL with content type text/
plain?

Thanks again
-Ryan
 
T

Thomas 'PointedEars' Lahn

kerinin said:
I'd like to be able to generate a text file in a web browser, then
supply a link which will allow users to save that file to disk. I'm
not trying to read from the local machine or even write directly to
the local machine, I'm simply trying to provide a file which the local
browser and save as it would any other URL.

MSHTML-based user agents at least since version 4.0 (e.g. IE 4.0+ for
Windows) and Gecko-based UAs since version 1.8 (e.g. Firefox 1.5+) [1] support

document.open("text/plain");
document.write("foo\nbar");
document.close();

where `document' is a reference to an object that implements `document' from
DOM Level 0 [2] and/or HTMLDocument from DOM Level 2 HTML [3] (but with this
proprietary extension). Meaning that it may also be

var w = window.open("", "...", "...");
w.document.open("text/plain");
...

The possible "link" would have to trigger another proprietary feature of the
UA's AOM. MSHTML at least since version 5.01 supports

document.execCommand("SaveAs", false, "C:\\foo\\bar.txt");

where the same conditions as described above apply. This opens a dialog
window that proposes to save the resource as C:\foo\bar.txt [4]

Passing `true' to prevent the "Save As" dialog from opening had no effect.
Probably that is because users would frown upon Web authors saving files to
their storage medium, other than cookies, without their explicit consent.
Omitting the target filename or suffix proposed to save the document as
(invalid) HTML with an .html suffix and the content wrapped in a `pre' element.


PointedEars
___________
[1] http://www.mozilla.org/projects/deerpark/new-web-dev-features.html
[2] http://docs.sun.com/source/816-6408-10/document.htm
http://developer.mozilla.org/en/docs/DOM:document
http://msdn2.microsoft.com/en-us/library/ms535862.aspx
[3] http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-26809268
[4] http://msdn2.microsoft.com/en-us/library/ms536419.aspx pp.
http://msdn2.microsoft.com/en-us/library/ms537418.aspx
 
P

Peter Michaux

The problem is that I don't want the server to have access to the data
- could the server send a blank document and then the client machine
could modify the text in it, or can the document.write functions only
operate on html Content-Types? Or alternately, could I open a new
window with javascript and specify a blank URL with content type text/
plain?

Seems like an odd thing to be doing.

I don't think there is any way to specify content type with
window.open().

You could dump the text in a textarea and tell the user to copy and
paste it.

Using a little flash movie you can put the content into the users
system clipboard and the user could paste it into a file. This
clobbers what is already in their clipboards so give them a warning.

Peter
 
P

Peter Michaux

Seems like an odd thing to be doing.

I don't think there is any way to specify content type with
window.open().

I meant to write "no cross-browser way".
 
V

VK

It is not exactly true. Any browser is an application to display HTML
documents. Any other type of document - including text/plain -
requires a separate plugin so to be displayed as separate object
withing HTML page. An exception is made for text/plain as a very
common type displayed in browsers. Instead of plugin, browser at
runtime generates a minimum HTML page
<HTML><BODY><PRE>text/plain content</PRE></BODY></HTML>
and displays it. This mechanics goes on the background, so if you say
saving a page, it will be again some.txt Unfortunately this mechanics
is not fully hidden on Gecko so say documentElement.firstChild returns
HEAD element for text/plain which may be very confusing if not knowing
the background mechanics.

Back to the OP question and as already pointed by Thomas, there is a
convenient solution for IE, much lesser convenient for Gecko - and
maybe newer Gecko has something better to propose and maybe IE7 has
more strict security for execCommand, needs to be checked. I am
talking only about solutions within the default security restrictions.

For IE one can use document.execCommand with SaveAs argument.
For Gecko one can use bug # 367231
https://bugzilla.mozilla.org/show_bug.cgi?id=367231
as it was explained to me by developers it is not a bug but a feature
so to remain in future releases.

So it maybe something like (test.txt file has to be in the same
directory where the page is in order to see the script in action):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>Save As</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<script type="text/javascript">
function saveAs(doc) {
if (typeof document.execCommand == 'object') {
doc.execCommand('SaveAs', false, 'C:\\foobar.txt');
}
else if (
(navigator.userAgent.indexOf('Gecko')!=-1) &&
(netscape) &&
(netscape.security)) {
var txt = doc.getElementsByTagName('PRE')[0].firstChild.nodeValue;
window.location = 'data:plain/text,' + escape(txt);
}
else {
}
}

function init() {
window.frames['UIN'].document.designMode = 'on';
}
window.onload = init;
</script>
</head>

<body>
<form method="post" action="">
<fieldset>
<legend>Save As</legend>
<iframe name="UIN" src="test.txt"
style="
width: 20em;
height: 3em;
display: -moz-inline-box;
display: inline-block;"></iframe>
<br>
<input type="button" value="Save As"
onclick="saveAs(window.frames['UIN'].document)">
</fieldset>
</form>

<noscript>
<p style="color:red">If you see this text then it means
that the current browser settings do not allow script
execution for this page.</p>
</noscript>
</body>
</html>
 
V

VK

Possible to generate text files in javascript?

<g>
It look like I have got a pair of k of bucks from the sky blue as a
solution like that for the default security was deadly needed for a
guy I know. JavaScript pays my Tahoe trip, who could think... :)

An updated solution - if anyone else needs it - could be like:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>Save As</title>
<script type="text/javascript">
/* (c) 2007 VK [[email protected]]
* All copyrights are given to the world.
*/
function saveAs(doc, path) {
if (('ActiveXObject' in window) &&
(typeof document.execCommand == 'object')) {
try {
doc.execCommand('SaveAs', false, path);
}
catch(e) {
window.alert('Save As error:\n'+
(e.number & 0xFFFF)+' '+e.message);
}
}
else if (('GeckoActiveXObject' in window) &&
(netscape) && (netscape.security)) {
var txt = doc.getElementsByTagName('PRE')[0].
firstChild.nodeValue;
window.location = saveAs.GeckoPrompt + escape(txt);
}
else {
window.alert('Required feature is missing');
}
}
saveAs.GeckoPrompt = 'data:TEXT FILE Please add .txt extension,';

function init() {
window.frames['UIN'].document.designMode = 'on';
}
window.onload = init;
</script>
</head>

<body>
<form action="" onsubmit="return false;">
<fieldset>
<legend>Save As</legend>
<p><iframe name="UIN" src="test.txt"
style="width:30em; height:3em;"></iframe></p>
<p><button type="button" accesskey="s"
onclick="
saveAs(window.frames['UIN'].document, 'C:\\foobar.txt')">
<u>S</u>ave</button></p>
</fieldset>
</form>

<noscript>
<p style="color:red">If you see this text then it means
that the current browser settings do not allow script
execution for this page.</p>
</noscript>

</body>
</html>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top