我正在尝试提供一种纯脚本解决方案,用于通过浏览器读取客户端计算机上的文件内容。
我有一个适用于 Firefox 和 Internet Explorer 的解决方案。它不漂亮,但我现在只是在尝试:
function getFileContents() {
var fileForUpload = document.forms[0].fileForUpload;
var fileName = fileForUpload.value;
if (fileForUpload.files) {
var fileContents = fileForUpload.files.item(0).getAsBinary();
document.forms[0].fileContents.innerHTML = fileContents;
} else {
// try the IE method
var fileContents = ieReadFile(fileName);
document.forms[0].fileContents.innerHTML = fileContents;
}
}
function ieReadFile(filename)
{
try
{
var fso = new ActiveXObject("Scripting.FileSystemObject");
var fh = fso.OpenTextFile(filename, 1);
var contents = fh.ReadAll();
fh.Close();
return contents;
}
catch (Exception)
{
return "Cannot open file :(";
}
}
我可以调用 getFileContents()
,它会将内容写入 fileContents
文本区域。
有没有办法在其他浏览器中做到这一点?
目前我最关心的是 Safari 和 Chrome,但我对任何其他浏览器的建议持开放态度。
编辑:针对这个问题,“你为什么要这样做?”:
基本上,我想在客户端将文件内容与一次性密码一起散列,以便我可以将此信息作为验证发回。
let a = await file.text();
编辑添加有关文件 API 的信息
自从我最初编写此答案以来,File API 已被提议作为标准和 implemented in most browsers(从 IE 10 开始,它增加了对此处描述的 FileReader
API 的支持,但还没有 File
API)。该 API 比旧的 Mozilla API 稍微复杂一些,因为它旨在支持文件的异步读取,更好地支持二进制文件和不同文本编码的解码。网上有 some documentation available on the Mozilla Developer Network 以及各种示例。您可以按如下方式使用它:
var file = document.getElementById("fileForUpload").files[0];
if (file) {
var reader = new FileReader();
reader.readAsText(file, "UTF-8");
reader.onload = function (evt) {
document.getElementById("fileContents").innerHTML = evt.target.result;
}
reader.onerror = function (evt) {
document.getElementById("fileContents").innerHTML = "error reading file";
}
}
原始答案
在 WebKit(因此,Safari 和 Chrome)中似乎没有办法做到这一点。 File 对象具有的唯一键是 fileName
和 fileSize
。根据对 File 和 FileList 支持的 commit message,它们受到 Mozilla's File object 的启发,但它们似乎只支持功能的子集。
如果您想更改此设置,您可以随时 send a patch 更改为 WebKit 项目。另一种可能性是提议将 Mozilla API 包含在 HTML 5 中; WHATWG 邮件列表可能是最好的地方。如果你这样做了,那么至少在几年内,更有可能会有一种跨浏览器的方式来做到这一点。当然,提交补丁或提案以纳入 HTML 5 确实意味着需要为这个想法辩护,但 Firefox 已经实现了它的事实为您提供了一些开始。
为了读取用户选择的文件,使用文件打开对话框,您可以使用 <input type="file">
标记。您可以找到 information on it from MSDN。选择文件后,您可以使用 FileReader API 读取内容。
函数 onFileLoad(elementId, event) { document.getElementById(elementId).innerText = event.target.result; } function onChooseFile(event, onLoadFileHandler) { if (typeof window.FileReader !== 'function') throw ("该浏览器不支持文件 API。");让输入 = event.target; if (!input) throw ("浏览器没有正确实现事件对象"); if (!input.files) throw ("此浏览器不支持文件输入的 `files` 属性。"); if (!input.files[0]) 返回未定义;让文件 = input.files[0];让 fr = new FileReader(); fr.onload = onLoadFileHandler; fr.readAsText(文件); }
有一个现代原生替代方案:File 实现 Blob,因此我们可以调用 Blob.text()。
异步函数 readText(event) { const file = event.target.files.item(0) const text = await file.text(); document.getElementById("output").innerText = text }
目前(2020 年 9 月)Chrome 和 Firefox 支持此功能,对于其他浏览器,您需要加载 polyfill,例如 blob-polyfill。
快乐编码!如果您在 Internet Explorer 上遇到错误,请更改安全设置以允许 ActiveX
var CallBackFunction = function(content) {
alert(content);
}
ReadFileAllBrowsers(document.getElementById("file_upload"), CallBackFunction);
//Tested in Mozilla Firefox browser, Chrome
function ReadFileAllBrowsers(FileElement, CallBackFunction) {
try {
var file = FileElement.files[0];
var contents_ = "";
if (file) {
var reader = new FileReader();
reader.readAsText(file, "UTF-8");
reader.onload = function(evt) {
CallBackFunction(evt.target.result);
}
reader.onerror = function(evt) {
alert("Error reading file");
}
}
} catch (Exception) {
var fall_back = ieReadFile(FileElement.value);
if (fall_back != false) {
CallBackFunction(fall_back);
}
}
}
///Reading files with Internet Explorer
function ieReadFile(filename) {
try {
var fso = new ActiveXObject("Scripting.FileSystemObject");
var fh = fso.OpenTextFile(filename, 1);
var contents = fh.ReadAll();
fh.Close();
return contents;
} catch (Exception) {
alert(Exception);
return false;
}
}
这工作正常
function onClick(event) {
filecontent = "";
var myFile = event.files[0];
var reader = new FileReader();
reader.addEventListener('load', function (e) {
filecontent = e.target.result;
});
reader.readAsBinaryString(myFile);
}
readAsText
之前不应该附加事件处理程序吗?