如何使用 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
可能是一个安全漏洞。 (要亲自查看此内容,请创建一个包含 <img src="/nonexistent" onerror="alert(1);">
之类的 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 打开本地磁盘文件?的主要内容,如果未能解决你的问题,请参考以下文章