使用JavaScript进行本地文件访问


177

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

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


Answers:


87

如果用户通过选择文件<input type="file">,则可以使用File API 读取处理该文件。

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

JavaScript和DOM为恶意作者提供了通过Web交付在客户端计算机上运行的脚本的潜力。浏览器作者使用两个限制来包含这种风险。首先,脚本在沙箱中运行,它们只能执行与Web相关的操作,而不能执行诸如创建文件之类的通用编程任务 。

2016更新:可以通过Filesystem API直接访问文件系统,该文件系统仅受Chrome和Opera支持,并且最终可能不会被其他浏览器实现Edge除外)。有关详细信息,请参见Kevin的答案


28
该死的。当然,这很愚蠢。据说Javascript是一种与应用程序无关的脚本语言。并非每个应用程序都是Web浏览器。我来到这里是因为,例如,我对脚本化Photoshop感兴趣。即使某些应用程序不提供文件访问类,也应将它们标准化为适合它们的那些应用程序-一种标准但可选的功能,因此即使不是通用的,也可以从一个应用程序中获得经验。我在Photoshop中学习的内容甚至无法移植到其他允许文件访问的Javascript主机上。
Steve314 2010年

27
用Java语言编写语言,并执行托管环境允许的所有操作。SpiderMonkey可以执行任何其他语言可以执行的操作。浏览器中的 Javascript 已沙箱化。

35
这个答案可能在3年前是正确的,但是肯定不再正确了。请参阅HTML5上的@Horst Walter的答案。或去这里: html5rocks.com/en/tutorials/file/dndfiles
james.garriss 2011年

@ james.garriss是的,实际上三年前也不是很正确。此页面教我如何在2003年使用Firefox进行读/写web.archive.org/web/20031229011919/http://www.captain.at/…(XUL的优点,但在XpCom的浏览器中可用),Microsoft 1990年代的node.js风格的javscript Shell脚本(和FileIO在ActiveX的浏览器中可用)
original_username

不再可能
SysDragon

158

http://www.html5rocks.com/zh-CN/tutorials/file/dndfiles/中只是HTML5功能的更新。这篇出色的文章将详细解释JavaScript中的本地文件访问。所提到文章的摘要:

该规范提供了几种用于从“本地”文件系统访问文件的接口:

  1. 文件-个人文件;提供只读信息,例如名称,文件大小,MIME类型以及对文件句柄的引用。
  2. FileList-File对象的类似数组的序列。(<input type="file" multiple>从桌面上考虑或拖动文件目录)。
  3. Blob-允许将文件切成字节范围。

请参阅下面的Paul D. Waite的评论。


7
它不像我们使用Java或Flash插件那样完全是一个真正的文件系统。例如,除非用户自己选择文件,否则我们无法在用户的桌面上列出文件。
Pacerier


4
考虑到W3C抢夺有用技术的形式,请当心。仅在chrome中实现的文件系统api不会继续进行。具有通用支持的文件 api 被接受为w3c工作草案,如果没有它,我们将无法想象生活。当然,我们仍在浏览器中,我们必须等待,直到用户将文件带给我们为止,但这极大地扩展了Web应用程序的范围,并且不会很快消失。
bbsimonbb

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,您只需在每次启动浏览器时执行一次)

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


6
这给出了一个不建议使用的错误,您只能在扩展程序中执行此操作,而不能在网站javascript中执行
Esailija 2012年

4
如此链接所示,此功能已在更高的firefox版本中删除。support.mozilla.org/en-US/questions/944433
Makan Tayebi 2013年

3
哦,真糟糕。我得到了安全性和所有这些保护,但是我们需要一种授予信任的方式来在本地运行我们自己的javascript文件。
杰森S

当然。而且我还没有找到另一种方法。
Makan Tayebi 2013年

2
请更新答案以表明它已被弃用。谢谢。
jpaugh 2015年

20

如前所述,FileSystemFile API以及FileWriter API可用于从浏览器选项卡/窗口的上下文读取文件并将其写入客户端计算机。

您应该了解与FileSystem和FileWriter API有关的几件事,其中提到了其中一些,但值得重复:

  • 目前仅在基于Chromium的浏览器(Chrome和Opera)中存在API的实现
  • 这两个API均已于2014年4月24日脱离W3C标准轨道,并且目前为专有
  • 将来有可能从实现浏览器中删除(现在是专有的)API
  • 沙箱(在磁盘上以外的位置,其中文件可以产生没有影响)用于存储与所述的API所创建的文件
  • 使用虚拟文件系统(目录结构不一定会以从浏览器内部进行访问时的形式存在于磁盘上)表示使用API​​创建的文件

以下是有关如何直接或间接使用API​​来完成这些操作的简单示例:

烘焙食品 *

写文件:

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

使用原始File,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不再处于标准轨道上,但在我看来,在某些情况下可以合理使用它们,因为:

  • 停用浏览器供应商的新兴趣可能使他们重新回到浏览器上
  • 实施(基于铬)浏览器的市场渗透率很高
  • Google(Chromium的主要贡献者)尚未给出API的使用期限和终止日期

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

* BakedGoods由这个人负责维护:)


7

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

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

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


1
也可以使用Electron访问本地文件,Electron是JavaScript桌面应用程序的类似框架。
安德森·格林

6

如果要在Windows上进行部署,则Windows脚本宿主为文件系统和其他本地资源提供了非常有用的JScript API。但是,将WSH脚本合并到本地Web应用程序中可能并不如您所愿。


3
我希望该解决方案与操作系统无关(至少在Windows和Mac之间),因此Windows脚本宿主无法满足要求,除非有适用于mac平台的类似解决方案
Jared

5

如果您输入像

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

4

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


1
IE,Mozilla或Safari当前不支持FSO.js。
菲利普·森

2

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

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

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

请在这里找到JSFS:https : //github.com/jsfsproject/jsfs。它是免费的,并根据GPL授权


1

假定用户可能直接允许使用JavaScript代码可能需要的任何文件。著名浏览器的创建者通常不允许JavaScript访问文件。

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

然后,使用readAsDataURL函数和FileReader对象将DataURL转换为文件。源代码和更完整的指南以及一个很好的示例位于:

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


0

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

必须安装Small Windows应用,页面中必须包含.js文件。

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

https://www.fathsoft.com/localfs


-4

如果您使用angularjs和aspnet / mvc来检索json文件,则必须在网络配置中允许mime类型

<staticContent>
    <remove fileExtension=".json" />
    <mimeMap fileExtension=".json" mimeType="application/json" />
  </staticContent>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.