0

I would like to add a function in my javascript to write to a text file in the local directory where the javascript file is located. This means I'm not looking for some insecure way of accessing the user's file system in any way. All I care about is extracting the user's input into an html page that is accessed by my javascript then using that input as data externally. I just need a simple text file. This user input isn't actually text by the way, but rather a bunch of actions using my online game's components that the underlying javascript turns into a text string (so this particular string is what I want to save, not really even anything direct from the user).

I don't want to write to a user's file system, but rather, the file where the javascript (and html) code is located (a folder hosted on a server). Is there any simple way to get some file I/O going?

I know Javascript has a FileReader, is there any way to get it to do this in reverse? Like a FileWriter. GoogleClosure looks like it has a FileWriter, but it doesn't seem to quite work and I can't find any decent examples of how to get it to do this.

If this requires a different language, is there any way I can just get the relevant snippet and insert this into my Javascript file? (the folder is hosted on a Linux system if that helps)

ADDENDUM: Elias Van Ootegem's solution below is excellent and I would highly recommend looking into it as it's a great example of client-server interaction and getting your system to provide you the data you're looking to extract. Workers are pretty interesting.

But for those of you looking at this post with that similar question that I initially had about JavaScript I/O, I found one other work-a-round depending on your case. My team's project site made use of a database site, MongoDB, that stored some of the user's interaction data if the user had hit a "Save" button. MongoDB, and other online database systems, provide a "dumping" function/script that you can call from your local machine/server and put that data into an output file (I was able to put the JSON data into a text file). From that output, you can write a parser to extract and format the data you desire from that output since databases like MongoDB can be pretty clear as to what format the text will be in (very structured, organized). I wrote a parser in C (with a few libraries I had written to extend the language) to do what I needed, but the idea is pretty generalizable to other programming/scripting languages.

I did look at leaving cookies as option as well, and made use of a test program to try it out (it works too!). However, one tradeoff for leaving cookies on a user's local system is that those cookies generally are meant to hold small amounts of data (usually things like username, date created, & expiration date of the cookie) and are dependent upon the user's local machine. Further, while you can extract the data in those cookies from JavaScript, you are back to the initial problem: the data still exists on the web, not on an output file on your server's file system. In the case you need to extract data and want some guarantee this data will exist on your machine, use Elias Van Ootegem's solution.

9codeMan9
  • 802
  • 6
  • 11
  • 25
  • look at this -> http://stackoverflow.com/questions/582268/read-write-to-file-using-jquery/582281#582281 – Kenneth Garza Apr 27 '13 at 20:04
  • Thanks @KennethGarza, that is more in line with what I was expecting. Though it requires learning AJAX and some server side language. – 9codeMan9 Apr 27 '13 at 20:15
  • 1
    you might want to consider other options, such as saving data as a cookie, or if you must have this as a more long term solution, you can use php to easily do what you want to do. There are 3rd party services such as Apigee that you can create a simple api solution (for free) that will save and retrieve data for you. Good luck – Kenneth Garza Apr 27 '13 at 20:25
  • if you don't mind @KennethGarza, do you have any good sources/links for writing a cookie in Javascript? (I found this: http://www.w3schools.com/js/js_cookies.asp). If I could get a cookie written, I could retrieve that cookie and extract the little bit of data stored in it and that would work perfectly. – 9codeMan9 Apr 27 '13 at 20:27
  • google is your friend :) -> http://stackoverflow.com/questions/11875273/writing-cookies-via-javascript – Kenneth Garza Apr 27 '13 at 20:28

1 Answers1

1

JavaScript code that is running client-side cannot access the server's filesystem at the same time, let alone write a file. People often say that, if JS were to have IO capabilities, that would be rather insecure... just imagine how dangerous that would be.

What you could do, is simply build your string, using a Worker that, on closing, returns the full data-string, which is then sent to the server (AJAX call).
The server-side script (Perl, PHP, .NET, Ruby...) can receive this data, parse it and then write the file to disk as you want it to.
All in all, not very hard, but quite an interesting project anyway. Oh, and when using a worker, seeing as it's an online game and everything, perhaps a setInterval to send (a part of) the data every 5000ms might not be a bad idea, either.

As requested - some basic code snippets.
A simple AJAX-setup function:

function getAjax(url,method, callback)
{
    var ret;
    method = method || 'POST';
    url = url || 'default.php';
    callback = callback || success;//assuming you have a default function called "success"
    try
    {
        ret = new XMLHttpRequest();
    }
    catch (error)
    {
        try
        {
            ret= new ActiveXObject('Msxml2.XMLHTTP');
        }
        catch(error)
        {
            try
            {
                ret= new ActiveXObject('Microsoft.XMLHTTP');
            }
            catch(error)
            {
                throw new Error('no Ajax support?');
            }
        }
    }
    ret.open(method, url, true);
    ret.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    ret.setRequestHeader('Content-type', 'application/x-www-form-urlencode');
    ret.onreadystatechange = callback;
    return ret;
 }
 var getRequest = getAjax('script.php?some=Get&params=inURL', 'GET');
 getRequest.send(null);
 var postRequest = getAjax('script.php', 'POST', function()
 {//passing anonymous function here, but this could just as well have been a named function reference, obviously...
    if (this.readyState === 4 && this.status === 200)
    {
         console.log('Post request complete, answer was: ' + this.response);
    }
 });
 postRequest.send('foo=bar');//set different headers to pos JSON.stringified data

Here's a good place to read up on whatever you don't get from the code above. This is, pretty much a copy-paste bit of code, but if you find yourself wanting to learn just a bit more, Here's a great place to do just that.

WebWorkers
Now these are pretty new, so using them does mean not being able to support older browsers (you could support them by using the event listeners to send each morsel of data to the server, but a worker allows you to bundle, pre-process and structure the data without blocking the "normal" flow of your script. Workers are often presented as a means to sort-of multi-thread JavaScript code. Here's a good intro to them
Basically, you'll need to add something like this to your script:

var worker = new Worker('preprocess.js');//or whatever you've called the worker
worker.addEventListener('message', function(e)
{
     var xhr = getAjax('script.php', 'post');//using default callback
     xhr.send('data=' + e.data);
     //worker.postMessage(null);//clear state
}, false);

Your worker, then, could start off like so:

var time, txt = '';
//entry point:
onmessage = function(e)
{
    if (e.data === null)
    {
        clearInterval(time);
        txt = '';
        return;
    }
    if (txt === '' && !time)
    {
        time = setInterval(function()
        {
            postMessage(txt);
        }, 5000);//set postMessage to be called every 5 seconds
    }
    txt += e.data;//add new text to current string...
}

Server-side, things couldn't be easier:

if ($_POST && $_POST['data'])
{
    $file = $_SESSION['filename'] ? $_SESSION['filename'] : 'File'.session_id();
    $fh = fopen($file, 'a+');
    fwrite($fh, $_POST['data']);
    fclose($fh);
}
echo 'ok';

Now all of this code is a bit crude, and most if it cannot be used in its current form, but it should be enough to get you started. If you don't know what something is, google it.
But do keep in mind that, when it comes to JS, MDN is easily the best reference out there, and as far as PHP goes, their own site (php.net/{functionName}) is pretty ugly, but does contain a lot of info, too...

Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
  • Yes, this is exactly what I was hoping for. Do you have any tutorials or links for quick ways I can write this "Worker"? Also for making an AJAX call in HTML5 or Javascript? In addition, writing the server-side script (in either PHP or .NET)? – 9codeMan9 Apr 27 '13 at 20:13
  • No, I was hoping you knew good resources/tutorials for learning how to make AJAX calls within JavaScript and any resources for writing server side scripts. Not the actual script I need but good resources you knew of (I know I can google it too in some cases). It seems that upon some initial Googling, I find specific cases of AJAX calls/questions, but I want something pure and simple to get started. I've been immersed in JavaScript for a long while for a project, jumping into other languages will be costly (this solution would require 2: AJAX, and .NET or PHP) – 9codeMan9 Apr 27 '13 at 21:10
  • *pure and simple with respect to the specific part of AJAX I need, not learning the entire language as that will be time-costly. Nonetheless, thank you for your help! – 9codeMan9 Apr 27 '13 at 21:22