【问题标题】:How to open a local disk file with JavaScript?如何使用 JavaScript 打开本地磁盘文件?
【发布时间】:2011-04-04 16:53:50
【问题描述】:

我试图打开文件

window.open("file:///D:/Hello.txt");

浏览器不允许以这种方式打开本地文件,可能是出于安全原因。我想在客户端使用文件的数据。如何在 JavaScript 中读取本地文件?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    你不能。 Firefox、Safari 等新浏览器会阻止“文件”协议。它只适用于旧浏览器。

    你必须上传你想要的文件。

    【讨论】:

      【解决方案2】:

      HTML5 fileReader facility 确实允许您处理本地文件,但这些文件必须由用户选择,您不能在用户磁盘上查找文件。

      我目前将它与 Chrome (6.x) 的开发版本一起使用。我不知道其他浏览器支持它。

      【讨论】:

      • 对,现在可以使用 HTML5。 Look here
      • 对参考规范的快速扫描(最后更新于 2012-07-12)显示没有文件写入功能,只有读取。
      • @Flavien Volken 不,这是不可能的。本地文件必须由用户选择
      【解决方案3】:

      Javascript 通常无法在新浏览器中访问本地文件,但 XMLHttpRequest 对象可用于读取文件。所以实际上是 Ajax(而不是 Javascript)在读取文件。

      如果要读取文件abc.txt,可以将代码写成:

      var txt = '';
      var xmlhttp = new XMLHttpRequest();
      xmlhttp.onreadystatechange = function(){
        if(xmlhttp.status == 200 && xmlhttp.readyState == 4){
          txt = xmlhttp.responseText;
        }
      };
      xmlhttp.open("GET","abc.txt",true);
      xmlhttp.send();
      

      现在txt 包含文件abc.txt 的内容。

      【讨论】:

      • @TheMuffinMan 和 XML。(异步 Javascript 和 XML)
      • 这个答案不相关,因为操作询问如何打开驻留在客户端的文件,而不是驻留在服务器上的文件。
      • @ThomasNguyen,这个问题是“javascript 打开文件”的第一个谷歌结果,这个答案仍然有益。
      • @ThomasNguyen 我同意,但没有 FileReader 的可能解决方法是将文件上传到服务器并从那里读取。我仍然对这个答案投了反对票。
      【解决方案4】:

      xmlhttp请求方法对本地磁盘上的文件无效,因为浏览器安全不允许我们这样做。但是我们可以通过创建快捷方式->右键单击->属性中的目标“来覆盖浏览器安全性。 .. browser location path.exe" append --allow-file-access-from-files。这是在 chrome 上测试的,但应注意关闭所有浏览器窗口,并且应从通过打开的浏览器运行代码这个快捷方式。

      【讨论】:

        【解决方案5】:

        这是一个使用FileReader的例子:

        function readSingleFile(e) {
          var file = e.target.files[0];
          if (!file) {
            return;
          }
          var reader = new FileReader();
          reader.onload = function(e) {
            var contents = e.target.result;
            displayContents(contents);
          };
          reader.readAsText(file);
        }
        
        function displayContents(contents) {
          var element = document.getElementById('file-content');
          element.textContent = contents;
        }
        
        document.getElementById('file-input')
          .addEventListener('change', readSingleFile, false);
        <input type="file" id="file-input" />
        <h3>Contents of the file:</h3>
        <pre id="file-content"></pre>

        规格

        http://dev.w3.org/2006/webapi/FileAPI/

        浏览器兼容性

        • IE 10+
        • 火狐3.6+
        • Chrome 13+
        • Safari 6.1+

        http://caniuse.com/#feat=fileapi

        【讨论】:

        • 只有一秒钟,当我重新加载相同的最后一个文件时,内容不会改变(我说的是它的内容,当我编辑文件文本时)。你能帮忙吗?
        • @SamusHands 是的,你是对的,我可以在 Safari 和 Chrome 中重现该问题(它在 Firefox 中运行良好)。在每个 onClick 事件上将输入值设置为 null 应该可以解决问题,请参阅:stackoverflow.com/a/12102992/63011
        • 这是FileReader 的一个很好的示例,但对上面的displayContents 进行评论:请注意,像这样使用不受信任的内容设置innerHTML 可能是一个安全漏洞。 (要亲自查看此内容,请创建一个包含 &lt;img src="/nonexistent" onerror="alert(1);"&gt; 之类的 bad.txt 并查看警报是否被执行——它可能是更多恶意代码。)
        • @ShreevatsaR 真的很好。我的 sn-p 只是一个例子,但你是对的,它不应该促进不良的安全习惯。我用textContent 替换了innerHTML。感谢您的评论。
        • @TeylerHalama 你也可以使用DOMContentLoaded 事件。
        【解决方案6】:

        因为我没有生命,我想要这 4 个声望点,这样我就可以向真正擅长编码的人表达我的爱(支持他们的答案)我分享了我对 Paolo Moretti 代码的改编。只需使用openFile(函数以文件内容作为第一个参数执行)

        function dispFile(contents) {
          document.getElementById('contents').innerHTML=contents
        }
        function clickElem(elem) {
        	// Thx user1601638 on Stack Overflow (6/6/2018 - https://stackoverflow.com/questions/13405129/javascript-create-and-save-file )
        	var eventMouse = document.createEvent("MouseEvents")
        	eventMouse.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
        	elem.dispatchEvent(eventMouse)
        }
        function openFile(func) {
        	readFile = function(e) {
        		var file = e.target.files[0];
        		if (!file) {
        			return;
        		}
        		var reader = new FileReader();
        		reader.onload = function(e) {
        			var contents = e.target.result;
        			fileInput.func(contents)
        			document.body.removeChild(fileInput)
        		}
        		reader.readAsText(file)
        	}
        	fileInput = document.createElement("input")
        	fileInput.type='file'
        	fileInput.style.display='none'
        	fileInput.onchange=readFile
        	fileInput.func=func
        	document.body.appendChild(fileInput)
        	clickElem(fileInput)
        }
        Click the button then choose a file to see its contents displayed below.
        <button onclick="openFile(dispFile)">Open a file</button>
        <pre id="contents"></pre>

        【讨论】:

        • 谢谢,很有帮助。尽管请注意,您可以直接调用fileInput.click(),而不是clickElem() 中的代码。 (至少在最新版本的 Chrome 中)
        • 对我有用,它所基于的代码不起作用。
        【解决方案7】:

        试试

        function readFile(file) {
          return new Promise((resolve, reject) => {
            let fr = new FileReader();
            fr.onload = x=> resolve(fr.result);
            fr.readAsText(file);
        })}
        

        但用户需要采取行动来选择文件

        function readFile(file) {
          return new Promise((resolve, reject) => {
            let fr = new FileReader();
            fr.onload = x=> resolve(fr.result);
            fr.readAsText(file);
        })}
        
        async function read(input) {
          msg.innerText = await readFile(input.files[0]);
        }
        <input type="file" onchange="read(this)"/>
        <h3>Content:</h3><pre id="msg"></pre>

        【讨论】:

        • 我刚刚看到了 msg.innerText,我第一次了解到一些用 ID 标识的元素可以使用 ID 作为窗口对象的变量名或属性来访问。
        • 所以答案是我们不能。 html 似乎非常适合文档交互!但并非所有东西都可以送达。本地文件访问会很好
        • @yota - 浏览器强制用户进行交互(并注意)可能是出于安全原因
        【解决方案8】:

        这里的其他人为此提供了相当详尽的代码。我不知道当时可能需要更复杂的代码。无论如何,我赞成其中一个,但这里有一个非常简化的版本,它的工作原理是一样的:

        function openFile() {
          document.getElementById('inp').click();
        }
        function readFile(e) {
          var file = e.target.files[0];
          if (!file) return;
          var reader = new FileReader();
          reader.onload = function(e) {
            document.getElementById('contents').innerHTML = e.target.result;
          }
          reader.readAsText(file)
        }
        Click the button then choose a file to see its contents displayed below.
        <button onclick="openFile()">Open a file</button>
        <input id="inp" type='file' style="visibility:hidden;" onchange="readFile(event)" />
        <pre id="contents"></pre>

        【讨论】:

          【解决方案9】:

          考虑将您的文件重新格式化为 javascript。 然后你可以简单地使用旧的加载它......

          <script src="thefileIwantToLoad.js" defer></script>
          

          【讨论】:

          • 在这种情况下,您可以格式化文件 as a base64 string 以将其保存在 JavaScript 文件中。
          【解决方案10】:

          如果 Blob 足够好,这里是如何在 typescript 中执行此操作(对于许多用例,无需通过 FileReader 转换为 ByteArray/String)

          function readFile({
            fileInput,
          }: {
            fileInput: HTMLInputElement;
          }): Promise<ArrayLike<Blob>> {
            return new Promise((resolve, reject) => {
              fileInput.addEventListener("change", () => {
                resolve(fileInput.files);
              });
            });
          }
          

          这里是如何在 vanilla javascript 中做到这一点

          function readFile({
            fileInput,
          }) {
            return new Promise((resolve, reject) => {
              fileInput.addEventListener("change", () => {
                resolve(fileInput.files);
              });
            });
          }
          
          

          【讨论】:

            【解决方案11】:

            与“安全原因”无关。它是本地的还是网络驱动器上的文件都没有关系。 Windows 操作系统的解决方案可能是 IIS - Internet Information Services 这是一些细节:
            要使用 Java Script window.open() 在浏览器中打开文件,该文件应该在 WEB 服务器上可用。
            通过在 IIS 上创建映射到任何物理驱动器的虚拟目录,您应该能够打开文件。 虚拟目录将有一些 http: 地址。 所以而不是 window.open("file:///D:/Hello.txt");
            你会写window.open("http://iis-server/MY_VIRTUAL_DRIVE_D/Hello.txt");

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2013-11-21
              • 2016-12-09
              • 1970-01-01
              相关资源
              最近更新 更多