如何使用 JavaScript 打开本地磁盘文件?

Posted

技术标签:

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

我试图打开文件

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

浏览器不允许以这种方式打开本地文件,可能是出于安全原因。我想在客户端使用文件的数据。如何在 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 应该可以解决问题,请参阅:***.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://***.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");

【讨论】:

以上是关于如何使用 JavaScript 打开本地磁盘文件?的主要内容,如果未能解决你的问题,请参考以下文章

Android浏览器如何打开本地html文件

mstsc连接远程桌面如何挂载本地磁盘

检查文件是不是存在于 javascript 和 HTML 中,如果您在本地打开页面

java里怎样弹出文件夹窗口,要我打开本地磁盘一样的效果。

python可以同步本地磁盘文件的字典

如何使用 vm、磁盘和本地文件副本正确处理 Azure 云的灾难恢复