192

是否有使用 JavaScript 完成的本地文件操作?我正在寻找一种无需安装足迹即可完成的解决方案,例如需要Adob​​e AIR

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

4

13 回答 13

162

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

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

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

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

于 2011-08-14T10:14:06.973 回答
96

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

设计不允许读取或写入任意文件。这是对沙盒的侵犯。来自维基百科 -> Javascript -> 安全性

JavaScript 和 DOM 为恶意作者提供了通过 Web 传递脚本以在客户端计算机上运行的可能性。浏览器作者使用两个限制来控制这种风险。首先,脚本在沙箱中运行,它们只能执行与 Web 相关的操作,而不是创建文件等通用编程任务 。

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

于 2008-12-16T19:12:43.450 回答
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,您只需在每次启动浏览器时执行一次)

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

于 2008-12-16T16:52:40.563 回答
21

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

您应该注意与 FileSystem 和 FileWriter API 有关的几件事,其中一些已被提及,但值得重复:

  • API 的实现目前仅存在于基于 Chromium 的浏览器(Chrome 和 Opera)中
  • 这两个 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 不再符合标准,但在我看来,在某些情况下使用它们是合理的,因为:

  • 未实施的浏览器供应商重新产生了兴趣,可能会让他们重新考虑
  • 实施(基于 ​​Chromium 的)浏览器的市场渗透率很高
  • 谷歌(Chromium 的主要贡献者)没有给出 API 的终止日期

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

*BakedGoods 由这里的这个人维护 :)

于 2016-07-07T19:51:30.410 回答
10

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

您可以使用它创建不需要任何安装的 windows、linux 或 mac 桌面应用程序。

于 2014-12-01T03:14:26.060 回答
6

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

于 2008-12-16T16:50:25.060 回答
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;
}
于 2017-10-23T14:03:52.517 回答
4

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

于 2014-03-08T18:45:12.930 回答
2

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

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

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

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

于 2013-12-06T21:24:41.637 回答
1

假设 JavaScript 代码可能需要的任何文件都应该由用户直接允许。著名浏览器的创建者一般不会让 JavaScript 访问文件。

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

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

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

于 2013-06-06T14:51:20.127 回答
1

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

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

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

https://www.fathsoft.com/localfs

于 2019-04-20T09:24:02.580 回答
1

我只是提到这一点,因为没有人提到这一点。我知道没有一种编程语言允许操作底层文件系统。所有编程语言都依赖操作系统中断来真正完成这些事情。在浏览器中运行的 JavaScript 只有浏览器“中断”才能使用,通常不会授予文件系统访问权限,除非已实现浏览器以支持此类中断。

据说,使用 JavaScript 访问文件系统的明显方法是使用 Node.js,它确实具有与底层操作系统直接交互的能力。

于 2020-07-20T21:02:43.330 回答
-5

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

<staticContent>
    <remove fileExtension=".json" />
    <mimeMap fileExtension=".json" mimeType="application/json" />
  </staticContent>
于 2016-01-25T07:44:43.287 回答