【发布时间】:2011-04-04 16:53:50
【问题描述】:
我试图打开文件
window.open("file:///D:/Hello.txt");
浏览器不允许以这种方式打开本地文件,可能是出于安全原因。我想在客户端使用文件的数据。如何在 JavaScript 中读取本地文件?
【问题讨论】:
标签: javascript
我试图打开文件
window.open("file:///D:/Hello.txt");
浏览器不允许以这种方式打开本地文件,可能是出于安全原因。我想在客户端使用文件的数据。如何在 JavaScript 中读取本地文件?
【问题讨论】:
标签: javascript
你不能。 Firefox、Safari 等新浏览器会阻止“文件”协议。它只适用于旧浏览器。
你必须上传你想要的文件。
【讨论】:
HTML5 fileReader facility 确实允许您处理本地文件,但这些文件必须由用户选择,您不能在用户磁盘上查找文件。
我目前将它与 Chrome (6.x) 的开发版本一起使用。我不知道其他浏览器支持它。
【讨论】:
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 的内容。
【讨论】:
xmlhttp请求方法对本地磁盘上的文件无效,因为浏览器安全不允许我们这样做。但是我们可以通过创建快捷方式->右键单击->属性中的目标“来覆盖浏览器安全性。 .. browser location path.exe" append --allow-file-access-from-files。这是在 chrome 上测试的,但应注意关闭所有浏览器窗口,并且应从通过打开的浏览器运行代码这个快捷方式。
【讨论】:
这是一个使用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/
【讨论】:
onClick 事件上将输入值设置为 null 应该可以解决问题,请参阅:stackoverflow.com/a/12102992/63011
FileReader 的一个很好的示例,但对上面的displayContents 进行评论:请注意,像这样使用不受信任的内容设置innerHTML 可能是一个安全漏洞。 (要亲自查看此内容,请创建一个包含 <img src="/nonexistent" onerror="alert(1);"> 之类的 bad.txt 并查看警报是否被执行——它可能是更多恶意代码。)
textContent 替换了innerHTML。感谢您的评论。
DOMContentLoaded 事件。
因为我没有生命,我想要这 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 中)
试试
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>
【讨论】:
这里的其他人为此提供了相当详尽的代码。我不知道当时可能需要更复杂的代码。无论如何,我赞成其中一个,但这里有一个非常简化的版本,它的工作原理是一样的:
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>
【讨论】:
考虑将您的文件重新格式化为 javascript。 然后你可以简单地使用旧的加载它......
<script src="thefileIwantToLoad.js" defer></script>
【讨论】:
如果 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);
});
});
}
【讨论】:
与“安全原因”无关。它是本地的还是网络驱动器上的文件都没有关系。
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");
【讨论】: