使用javascript进行本地文件访问

时间:2008-12-16 16:43:00

标签: javascript file-access

是否有使用JavaScript完成的本地文件操作?我正在寻找一种可以在没有安装空间的情况下完成的解决方案,例如需要AIR。

具体来说,我想从文件中读取内容并将这些内容写入另一个文件。在这一点上,我并不担心获得权限,只是假设我已经拥有对这些文件的完全权限。

14 个答案:

答案 0 :(得分:157)

只是HTML5功能的更新http://www.html5rocks.com/en/tutorials/file/dndfiles/这篇优秀的文章将详细解释Javascript中的本地文件访问。上述文章摘要:

规范为accessing files from a 'local' filesystem提供了几个接口:

  1. 文件 - 单个文件;提供只读信息,例如名称,文件大小,mimetype和对文件句柄的引用。
  2. FileList - 类似于数组的File对象序列。 (想一想<input type="file" multiple>或从桌面拖动文件目录)。
  3. Blob - 允许将文件切片为字节范围。
  4. - 编辑 -

    见Paul D. Waite的评论

答案 1 :(得分:81)

如果用户通过<input type="file">选择了一个文件,您可以使用read processFile API提交文件。

设计不允许读取或写入任意文件。这违反了沙箱。来自Wikipedia -> Javascript -> Security

  

JavaScript和DOM提供   恶意作者的潜力   提供在客户端上运行的脚本   电脑通过网络。浏览器作者   使用两个包含此风险   限制。首先,脚本运行在   他们只能执行的沙箱   网络相关的行动,而不是   通用编程任务,如   创建文件

2016年更新:可以通过Filesystem API only supported by Chrome and Operamay end up not being implemented by other browsersexception of Edge)直接访问文件系统。有关详细信息,请参阅Kevin's answer

答案 2 :(得分:21)

更新自Firefox 17以来,此功能已被删除(请参阅https://bugzilla.mozilla.org/show_bug.cgi?id=546848)。


在Firefox上,你(程序员)可以在JavaScript文件中执行此操作:

netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserWrite");

将提示您(浏览器用户)允许访问。 (对于Firefox,您只需在每次启动浏览器时执行此操作一次)

如果浏览器用户是其他人,则必须授予权限。

答案 3 :(得分:18)

如前所述,FileSystemFile API以及FileWriter API可用于从浏览器标签/窗口的上下文读取和写入文件到客户机。

有几个与FileSystem和FileWriter API有关的事情,你应该知道,其中一些被提到,但值得重复:

  • API的实现目前仅存在于基于Chromium的浏览器(Chrome&amp; Opera)
  • 这两个API于2014年4月24日从W3C标准轨道中删除,截至目前为专有
  • 将来可能会从实现浏览器中删除(现在专有的)API
  • 沙箱(磁盘上的文件无法生效的位置)用于存储使用API​​创建的文件
  • 使用虚拟文件系统(一种不一定存在于磁盘上的目录结构,其形式与在浏览器中访问时相同)代表使用API​​创建的文件

这里有一些简单的例子,说明如何直接和间接地使用API​​来做这些事情:

<强> BakedGoods *

写文件:

bakedGoods.set({
    data: [{key: "testFile", value: "Hello world!", dataFormat: "text/plain"}],
    storageTypes: ["fileSystem"],
    options: {fileSystem:{storageType: Window.PERSISTENT}},
    complete: function(byStorageTypeStoredItemRangeDataObj, byStorageTypeErrorObj){}
});

读取文件:

bakedGoods.get({
        data: ["testFile"],
        storageTypes: ["fileSystem"],
        options: {fileSystem:{storageType: Window.PERSISTENT}},
        complete: function(resultDataObj, byStorageTypeErrorObj){}
});

使用原始文件,FileWriter和FileSystem API

写文件:

function onQuotaRequestSuccess(grantedQuota)
{

    function saveFile(directoryEntry)
    {

        function createFileWriter(fileEntry)
        {

            function write(fileWriter)
            {
                var dataBlob = new Blob(["Hello world!"], {type: "text/plain"});
                fileWriter.write(dataBlob);              
            }

            fileEntry.createWriter(write);
        }

        directoryEntry.getFile(
            "testFile", 
            {create: true, exclusive: true},
            createFileWriter
        );
    }

    requestFileSystem(Window.PERSISTENT, grantedQuota, saveFile);
}

var desiredQuota = 1024 * 1024 * 1024;
var quotaManagementObj = navigator.webkitPersistentStorage;
quotaManagementObj.requestQuota(desiredQuota, onQuotaRequestSuccess);

读取文件:

function onQuotaRequestSuccess(grantedQuota)
{

    function getfile(directoryEntry)
    {

        function readFile(fileEntry)
        {

            function read(file)
            {
                var fileReader = new FileReader();

                fileReader.onload = function(){var fileData = fileReader.result};
                fileReader.readAsText(file);             
            }

            fileEntry.file(read);
        }

        directoryEntry.getFile(
            "testFile", 
            {create: false},
            readFile
        );
    }

    requestFileSystem(Window.PERSISTENT, grantedQuota, getFile);
}

var desiredQuota = 1024 * 1024 * 1024;
var quotaManagementObj = navigator.webkitPersistentStorage;
quotaManagementObj.requestQuota(desiredQuota, onQuotaRequestSuccess);

虽然FileSystem和FileWriter API不再符合标准,但在我看来,在某些情况下,它们的使用是合理的,因为:

  • 来自未实施的浏览器供应商的重新兴趣可能会将它们重新置于其上
  • 实施(基于Chromium)浏览器的市场渗透率很高
  • Google(Chromium的主要贡献者)尚未提供API的终止日期

然而,“某些情况”是否包含您自己的情况,由您决定。

* BakedGoods由这个人维持在这里:)

答案 4 :(得分:7)

NW.js允许您使用Javascript创建桌面应用程序,而不存在通常放在浏览器上的所有安全限制。因此,您可以使用函数运行可执行文件,或创建/编辑/读取/写入/删除文件。您可以访问硬件,例如当前的CPU使用率或使用的总RAM等。

您可以使用它创建一个不需要任何安装的Windows,Linux或Mac桌面应用程序。

这是NW.js的框架,通用GUI:

答案 5 :(得分:6)

如果您在Windows上部署,Windows Script Host为文件系统和其他本地资源提供了非常有用的JScript API。但是,将WSH脚本合并到本地Web应用程序可能并不像您希望的那样优雅。

答案 6 :(得分:4)

如果你有像

这样的输入字段
<input type="file" id="file" name="file" onchange="add(event)"/>

您可以使用BLOB格式获取文件内容:

function add(event){
  var userFile = document.getElementById('file');
  userFile.src = URL.createObjectURL(event.target.files[0]);
  var data = userFile.src;
}

答案 7 :(得分:3)

FSO.js包含了由W3C标准化的新HTML5 FileSystem API,并提供了一种非常简单的方式来读取,写入或遍历本地沙盒文件系统。它是异步的,因此文件IO不会干扰用户体验。 :)

答案 8 :(得分:2)

如果您需要访问客户端上的整个文件系统,读取/写入文件,查看文件夹以进行更改,启动应用程序,加密或签署文档等,请查看JSFS。

它允许从您的网页安全无限制地访问客户端上的计算机资源,而无需使用AcitveX或Java Applet等浏览器插件技术。但是,必须安装软件的和平。

为了使用JSFS,您应该具备Java和Java EE开发(Servlet)的基本知识。

请在此处找到JSFS:https://github.com/jsfsproject/jsfs。它是免费的,并根据GPL许可

答案 9 :(得分:1)

假设js可能需要的任何文件应该由用户直接允许,着名浏览器的创建者一般不允许javascript访问文件。

解决方案的主要思想是:javascript无法通过拥有本地URL来访问该文件。 但是它可以通过使用它的DataURL来使用该文件:因此,如果用户浏览文件并打开它,js应该直接从HTML获取“DataURL”而不是获取“URL”。

然后使用readAsDataURL函数和FileReader对象将DataURL转换为文件。 来源和更完整的指南,有一个很好的例子:

https://developer.mozilla.org/en-US/docs/Web/API/FileReader?redirectlocale=en-US&redirectslug=DOM%2FFileReader

答案 10 :(得分:0)

有一个(商业)产品“ localFS”,可用于在客户端计算机上读取和写入整个文件系统。

必须安装小型Windows应用程序,并且页面中必须包含小型.js文件。

作为一项安全功能,可以将文件系统访问限制为一个文件夹,并使用密钥进行保护。

https://www.fathsoft.com/localfs

答案 11 :(得分:0)

我只提到这一点,因为没有人提到这一点。我知道没有一种编程语言可以允许对底层文件系统进行操作。所有编程语言都依赖于OS中断来实际完成这些操作。在浏览器中运行的JavaScript仅具有可与浏览器“中断”配合使用的功能,除非将浏览器实现为支持此类中断,否则通常不会授予文件系统访问权限。

可以说,使用JavaScript进行文件系统访问的一种明显方法是使用Node.js,它确实具有直接与基础操作系统进行交互的功能。

答案 12 :(得分:0)

您可以通过使用浏览器框外的 node.js fs 模块来实现这一点

答案 13 :(得分:-4)

  

如果你正在使用angularjs&amp; aspnet / mvc,检索json文件,你   必须在web配置中允许mime类型

<staticContent>
    <remove fileExtension=".json" />
    <mimeMap fileExtension=".json" mimeType="application/json" />
  </staticContent>