JavaScript:在有限的内容中编写输出文件。安全方案

时间:2013-04-27 20:01:25

标签: javascript html5 file-io filewriter

我想在我的javascript中添加一个函数来写入javascript文件所在的本地目录中的文本文件。这意味着我不会寻找以任何方式访问用户文件系统的不安全方式。我所关心的只是将用户的输入提取到一个html页面,该页面由我的javascript访问,然后使用该输入作为外部数据。我只需要一个简单的文本文件。顺便说一句,这个用户输入实际上不是文本,而是使用我的在线游戏组件的一堆操作,底层的javascript变成了一个文本字符串(所以这个特定的字符串是我想保存的,甚至不是任何直接来自用户)。

我不想写入用户的文件系统,而是写入javascript(和html)代码所在的文件(托管在服务器上的文件夹)。有没有简单的方法来获取文件I / O?

我知道Javascript有一个FileReader,有没有办法让它反向执行此操作?像FileWriter一样。 GoogleClosure看起来好像有一个FileWriter,但它似乎没有完全奏效,我找不到任何体面的例子来说明如何做到这一点。

如果这需要不同的语言,有什么方法可以获取相关的片段并将其插入到我的Javascript文件中? (如果有帮助,该文件夹托管在Linux系统上)

ADDENDUM: Elias Van Ootegem的解决方案非常出色,我强烈建议您查看它,因为它是客户端 - 服务器交互的一个很好的示例,让您的系统为您提供所需的数据提取。工人非常有趣。

但是对于那些看到这篇文章的人来说我最初对JavaScript I / O有类似的问题,我根据你的情况发现了另外一个工作。我的团队的项目站点使用了一个数据库站点MongoDB,如果用户点击了“保存”按钮,它会存储一些用户的交互数据。 MongoDB和其他在线数据库系统提供了一个“转储”功能/脚本,您可以从本地计算机/服务器调用该脚本并将该数据放入输出文件(我能够将JSON数据放入文本文件中)。从该输出中,您可以编写一个解析器来从该输出中提取和格式化您想要的数据,因为像MongoDB这样的数据库可以非常清楚文本将采用何种格式(非常结构化,有条理)。我在C中编写了一个解析器(我编写了一些扩展语言的库)来完成我需要的工作,但这个想法很适合其他编程/脚本语言。

我确实考虑过将cookie作为选项,并使用测试程序来试用它(它也有效!)。但是,在用户本地系统上留下cookie的一个权衡是,这些cookie通常用于保存少量数据(通常包括用户名,创建日期和Cookie的过期日期)并且取决于用户的本地计算机。此外,虽然您可以从JavaScript中提取这些cookie中的数据,但您回到了最初的问题:数据仍然存在于Web上,而不是存储在服务器文件系统上的输出文件中。如果您需要提取数据并希望保证这些数据存在于您的机器上,请使用Elias Van Ootegem的解决方案。

1 个答案:

答案 0 :(得分:1)

运行客户端的JavaScript代码无法同时访问服务器的文件系统,更不用说编写文件了。人们常说,如果JS拥有IO功能,那将是相当不安全的......想象一下会有多么危险。

你可以做的,就是使用Worker构建你的字符串,在结束时返回完整的数据字符串,然后发送到服务器(AJAX调用)。
服务器端脚本(Perl,PHP,.NET,Ruby ...)可以接收此数据,解析它,然后根据需要将文件写入磁盘。
总而言之,不是很难,但无论如何都是一个非常有趣的项目。哦,当使用工作人员时,看到它是一个在线游戏和所有内容,或许setInterval每隔5000ms发送(部分)数据也可能不是一个坏主意。

根据要求 - 一些基本代码片段 一个简单的AJAX设置功能:

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。这几乎是一个复制粘贴的代码,但如果你发现自己想要多学习一点,Here's a great place to do just that

WebWorkers
现在这些都是新的,所以使用它们意味着无法支持旧浏览器(您可以通过使用事件侦听器将每个数据发送到服务器来支持它们,但是工作人员允许您捆绑,预处理和在不阻塞脚本“正常”流程的情况下构建数据。工作人员通常被用作排序多线程JavaScript代码的工具。Here's a good intro to them
基本上,您需要在脚本中添加类似的内容:

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);

然后,你的工人可以这样开始:

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...
}

服务器端,事情变得更加容易:

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

现在所有这些代码都有点粗糙,而且大多数代码都不能以当前形式使用,但它应该足以让你开始。如果您不知道是什么,请谷歌。
但请记住,当涉及到JS时,MDN很容易成为最好的参考,就PHP来说,their own site(php.net / {functionName})非常丑陋,但确实包含很多信息......