【问题标题】:JavaScript: Create and save file [duplicate]JavaScript:创建和保存文件[重复]
【发布时间】:2012-11-04 12:02:46
【问题描述】:

我有想要写入文件的数据,并打开一个文件对话框供用户选择保存文件的位置。如果它可以在所有浏览器中运行,那就太好了,但它必须在 Chrome 中运行。我想在客户端做这一切。

基本上我想知道在这个函数中放什么:

saveFile: function(data)
{
}

函数在哪里接收数据,让用户选择一个位置来保存文件,并在该位置创建一个包含该数据的文件。

如果有帮助的话,使用 HTML 也可以。

【问题讨论】:

标签: javascript file dialog save


【解决方案1】:

您不能仅在 Javascript 中执行此操作。由于安全原因,在浏览器上运行的 Javascript 还没有足够的权限(有提议)。

相反,我建议使用Downloadify

一个小型 javascript + Flash 库,无需服务器交互即可创建和下载文本文件。

您可以看到一个简单的演示 here,您可以在其中提供内容并测试保存/取消/错误处理功能。

【讨论】:

    【解决方案2】:

    对于最新的浏览器,例如 Chrome,您可以使用File API as in this tutorial

    window.requestFileSystem  = window.requestFileSystem || window.webkitRequestFileSystem;
    window.requestFileSystem(window.PERSISTENT, 5*1024*1024 /*5MB*/, saveFile, errorHandler);
    

    【讨论】:

    【解决方案3】:

    github 上的这个项目看起来很有希望:

    https://github.com/eligrey/FileSaver.js

    FileSaver.js 实现了 W3C saveAs() FileSaver 接口 原生不支持它的浏览器。

    还可以在这里查看演示:

    http://eligrey.com/demos/FileSaver.js/

    【讨论】:

    • w3.org/TR/file-writer-api/#the-filesaver-interface 说“此文档的工作已停止,不应引用或用作实施的基础。”
    • "实现 w3C saveAs"???那是什么?演示没用,没有代码。
    • 所有代码都在 git 中可用,正如人们所期望的那样。不确定“那是什么”的目的是什么?评论是。如果它真的想知道它是什么,那么w3.org/TR/file-writer-api 会有所帮助。如果它指出项目已被取消,则该信息在 git 的 README 中。
    • @Godsmith,我认为这并不重要,因为它似乎回退到 createObjectURL 或任何可以保存文件的方法,并尽可能地处理浏览器差异。
    【解决方案4】:

    在创建文件之前选择保存文件的位置是不可能的。但至少在 Chrome 中,仅使用 JavaScript 生成文件是可能的。这是我创建 CSV 文件的一个旧示例。将提示用户下载它。不幸的是,这在其他浏览器中效果不佳,尤其是 IE。

    <!DOCTYPE html>
    <html>
    <head>
        <title>JS CSV</title>
    </head>
    <body>
        <button id="b">export to CSV</button>
        <script type="text/javascript">
            function exportToCsv() {
                var myCsv = "Col1,Col2,Col3\nval1,val2,val3";
    
                window.open('data:text/csv;charset=utf-8,' + escape(myCsv));
            }
    
            var button = document.getElementById('b');
            button.addEventListener('click', exportToCsv);
        </script>
    </body>
    </html>
    

    【讨论】:

    • 当我使用它时,它会打开一个包含文本的新选项卡,它不会打开文件对话框窗口。
    • @user1756980 - 是的。您需要从该新标签中“保存到文件”。
    • 这取决于浏览器,操作系统等。在我写答案的时候,Chrome中的一个csv数据url会弹出一个保存对话框
    • @JesseChisholm 你可以在javascript中做到这一点。只需在变量中创建一个锚标记并将下载属性放在上面(如:a.download = "downloadname.txt"),然后使用 a.click() 单击它。
    【解决方案5】:

    Javascript 有一个 FileSystem API。如果您可以处理让该功能仅在 Chrome 中运行,一个很好的起点是:http://www.html5rocks.com/en/tutorials/file/filesystem/

    【讨论】:

      【解决方案6】:

      function download(text, name, type) {
        var a = document.getElementById("a");
        var file = new Blob([text], {type: type});
        a.href = URL.createObjectURL(file);
        a.download = name;
      }
      <a href="" id="a">click here to download your file</a>
      <button onclick="download('file text', 'myfilename.txt', 'text/plain')">Create file</button>

      然后您可以通过将下载属性放在锚标记上来下载文件。

      我喜欢这个比创建数据 url 更好的原因是你不必制作一个很大的长 url,你可以生成一个临时 url。

      【讨论】:

      • @Banjocat 您应该检查浏览器是否支持某些对象。检测示例:if("URL"in window&amp;&amp;"createObjectURL"in URL&amp;&amp;"download"in Element.prototype): 否则,您只需更改下载方法或注意到浏览器不支持下载文件所需的对象。
      • 在 Firefox 中,如果您单击链接,这将起作用,但如果您右键单击并选择将链接另存为... 则没有任何反应。
      • 在谷歌浏览器中不起作用:Download is disallowed. The frame initiating or instantiating the download is sandboxed, but the flag ‘allow-downloads’ is not set. See https://www.chromestatus.com/feature/5706745674465280 for more details.
      • @posfan12 尝试在自己的页面中实现,SO 将代码 sn-p 呈现在 iframe 中,如果没有允许下载标志,则不允许下载文件。
      【解决方案7】:

      在控制台中尝试过,它可以工作。

      var aFileParts = ['<a id="a"><b id="b">hey!</b></a>'];
      var oMyBlob = new Blob(aFileParts, {type : 'text/html'}); // the blob
      window.open(URL.createObjectURL(oMyBlob));
      

      【讨论】:

        【解决方案8】:

        Awesomeness01(不需要锚标签)对代码进行了非常小的改进,并按照trueimage(支持 IE)的建议进行了添加:

        // Function to download data to a file
        function download(data, filename, type) {
            var file = new Blob([data], {type: type});
            if (window.navigator.msSaveOrOpenBlob) // IE10+
                window.navigator.msSaveOrOpenBlob(file, filename);
            else { // Others
                var a = document.createElement("a"),
                        url = URL.createObjectURL(file);
                a.href = url;
                a.download = filename;
                document.body.appendChild(a);
                a.click();
                setTimeout(function() {
                    document.body.removeChild(a);
                    window.URL.revokeObjectURL(url);  
                }, 0); 
            }
        }
        

        经测试可在 Chrome、FireFox 和 IE10 中正常运行。

        在 Safari 中,数据会在新选项卡中打开,因此必须手动保存此文件。

        【讨论】:

        • 具体是哪个版本的IE?
        • 这在 IE 11.0.9600.18426 中不起作用,但在 Chrome 52.0.2743.116 m 中起作用。有什么想法可以让它在 IE 11 中运行?
        • 在我看来 var a = document.createElement("a") 应该在 else 分支中,否则 IE10+ 将创建但不会删除锚 (&lt;a&gt;) 元素。
        • 在 Safari 中似乎不起作用,只是没有任何反应(不保存)
        • 下载时如何在此脚本中设置位置?
        【解决方案9】:

        对于 Chrome 和 Firefox,我一直使用纯 JavaScript 方法。

        (我的应用程序不能使用像 Blob.js 这样的包,因为它是由一个特殊的引擎提供服务的:一个带有 WWWeb 服务器的 DSP,几乎没有空间容纳任何东西。)

        function FileSave(sourceText, fileIdentity) {
            var workElement = document.createElement("a");
            if ('download' in workElement) {
                workElement.href = "data:" + 'text/plain' + "charset=utf-8," + escape(sourceText);
                workElement.setAttribute("download", fileIdentity);
                document.body.appendChild(workElement);
                var eventMouse = document.createEvent("MouseEvents");
                eventMouse.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
                workElement.dispatchEvent(eventMouse);
                document.body.removeChild(workElement);
            } else throw 'File saving not supported for this browser';
        }
        

        注意事项、警告和黄鼠狼语:

        • 我已在 Linux (Maipo) 和 Windows(7 和 10)环境中运行的 Chrome 和 Firefox 客户端中成功使用此代码。
        • 但是,如果sourceText 大于 MB,Chrome 有时(仅有时)会卡在自己的下载中而没有任何失败指示;到目前为止,Firefox 还没有表现出这种行为。原因可能是 Chrome 中的一些 blob 限制。坦率地说,我只是不知道;如果有人对如何纠正(或至少检测)有任何想法,请发布。如果出现下载异常,当 Chrome 浏览器关闭时,它会生成诊断信息,例如
        • 此代码与 Edge 或 Internet Explorer 不兼容;我没有尝试过 Opera 或 Safari。

        【讨论】:

          【解决方案10】:

          StreamSaver 是一种替代方法,可以保存非常大的文件,而不必将所有数据保存在内存中。
          事实上,它模拟了服务器在保存文件时所做的一切,但所有客户端都使用 service worker。

          您可以获取 writer 并手动向其写入 Uint8Array,也可以通过管道将二进制 readableStream 传输到可写流

          有几个example在展示:

          • 如何将多个文件保存为 zip
          • 将 readableStream 从例如 Responseblob.stream() 传送到 StreamSaver
          • 在您键入内容时手动写入可写流
          • 或重新编码视频/音频

          这是一个最简单的例子:

          const fileStream = streamSaver.createWriteStream('filename.txt')
          
          new Response('StreamSaver is awesome').body
            .pipeTo(fileStream)
            .then(success, error)
          

          如果要保存 blob,只需将其转换为 readableStream

          new Response(blob).body.pipeTo(...) // response hack
          blob.stream().pipeTo(...) // feature reference
          

          【讨论】:

          • 这看起来是一个非常有用的库。谢谢!
          【解决方案11】:
          function SaveBlobAs(blob, file_name) {
              if (typeof navigator.msSaveBlob == "function")
                  return navigator.msSaveBlob(blob, file_name);
          
              var saver = document.createElementNS("http://www.w3.org/1999/xhtml", "a");
              var blobURL = saver.href = URL.createObjectURL(blob), 
                  body = document.body;
          
              saver.download = file_name;
          
              body.appendChild(saver);
              saver.dispatchEvent(new MouseEvent("click"));
              body.removeChild(saver);
              URL.revokeObjectURL(blobURL);
          }
          

          【讨论】:

            【解决方案12】:

            function download(text, name, type) {
              var a = document.getElementById("a");
              var file = new Blob([text], {type: type});
              a.href = URL.createObjectURL(file);
              a.download = name;
            }
            <a href="" id="a">click here to download your file</a>
            <button onclick="download('file text', 'myfilename.json', 'text/json')">Create file</button>

            如果您更改 mime 类型,我认为这也适用于 json 文件。

            【讨论】:

              猜你喜欢
              • 2011-12-04
              • 1970-01-01
              • 1970-01-01
              • 2023-02-13
              • 2014-02-16
              • 1970-01-01
              • 2018-04-11
              • 1970-01-01
              相关资源
              最近更新 更多