在JavaScript中使用本地文件作为数据源
背景: 我想制作一个“应用程序”,它只使用JavaScript/HTML,可以由浏览器直接从文件系统打开。此应用程序必须能够从其他文件读取数据。然后我将使用JS解析它并呈现页面。作为一个简化的示例,假设我有一个CSV文件: 我希望能够使用JS读取文件,并使用其中的数据生成我的页面 我迄今为止的成就: (右键单击->“另存为”将HTML保存到计算机)。它也以半破损的方式在上可用(布局已破损,但功能上仍应正确) 只需将CSV文本文件拖放到拖放框中,或使用文件菜单选择文本文件,JavaScript将读取、解析文件并填充表格 这依赖于FileReader API;大多数重型起重作业都是通过此功能完成的:在JavaScript中使用本地文件作为数据源,javascript,html,file,filereader,Javascript,Html,File,Filereader,背景: 我想制作一个“应用程序”,它只使用JavaScript/HTML,可以由浏览器直接从文件系统打开。此应用程序必须能够从其他文件读取数据。然后我将使用JS解析它并呈现页面。作为一个简化的示例,假设我有一个CSV文件: 我希望能够使用JS读取文件,并使用其中的数据生成我的页面 我迄今为止的成就: (右键单击->“另存为”将HTML保存到计算机)。它也以半破损的方式在上可用(布局已破损,但功能上仍应正确) 只需将CSV文本文件拖放到拖放框中,或使用文件菜单选择文本文件,JavaScript将读
function handleFileSelect(evt) {
evt.stopPropagation();
evt.preventDefault();
var files = evt.target.files || evt.dataTransfer.files; // FileList object.
var file = files[0];
// this creates the FileReader and reads stuff as text
var fr = new FileReader();
fr.onload = parse;
fr.readAsText(file);
// this is the function that actually parses the file
// and populates the table
function parse()
{
var table = document.getElementById('emps');
var employees = fr.result.split('\n'); var c = 0;
for (var i in employees)
{
var employee = employees[i].split(',');
if (employee.length == 3)
{
var row = document.createElement('tr');
row.innerHTML = "<td>" + employee.join("</td><td>") + "</td>";
table.appendChild(row);
c++;
}
}
document.getElementById('result').innerHTML = '<span>Added ' + c + ' employees from file: ' + file.name + '</span>';
}
}
功能手柄文件选择(evt){
evt.stopPropagation();
evt.preventDefault();
var files=evt.target.files | | evt.dataTransfer.files;//文件列表对象。
var file=files[0];
//这将创建文件阅读器并将内容作为文本读取
var fr=new FileReader();
fr.onload=parse;
fr.readAsText(文件);
//这是实际解析文件的函数
//并填充表
函数解析()
{
var table=document.getElementById('emps');
var employees=fr.result.split('\n');var c=0;
用于(员工中的var i)
{
var employee=employees[i]。拆分(',');
如果(employee.length==3)
{
var行=document.createElement('tr');
row.innerHTML=”“+employee.join(“”+“”);
表2.追加子项(行);
C++;
}
}
document.getElementById('result').innerHTML='从文件'+file.name+''中添加'+c+'员工;
}
}
这几乎没问题,但它不方便用户手动加载文件。理想情况下,它应该能够自动加载,但出于安全原因,没有浏览器会允许。。。然而
解决方案要求:
- 必须离线工作;ie:它不能依赖任何在线服务。这还包括在本地计算机上运行的HTTP服务器。其想法是在任何只安装了浏览器的计算机上运行
- 当使用
协议(即:硬盘上的HTML页面)打开页面时,必须工作文件://
- 不应该依赖第三方附加组件(例如:Flash、Java、抖动ActiveX)。我很确定,如果页面位于
文件中://
- 它必须能够接受任意的数据。这就排除了以行为良好的格式加载已准备好使用的文件的可能性 比如JSON
- 如果它可以在Firefox或Chrome上运行(理想情况下两者都可以),那就好了。依赖实验性API也是可以的
因此,如果有一个聪明的黑客将一个文件加载到一个页面中也很好(可能将其加载到一个不可见的iframe中,让JS检索内容);那也没关系 以下是我用于Firefox的代码,它不可移植,但可以工作: 正如OP评论的那样,
enablePrivilege()
已被弃用,这应该被认为是可用的。但是,由于我的Firefox使用以前的配置文件时仍然可以使用我的代码,因此我深入研究了prefs.js
(因为about:config
隐藏了这些设置),下面是您需要的设置,以使其正常工作
user_pref("capability.principal.codebase.p0.granted", "UniversalXPConnect");
user_pref("capability.principal.codebase.p0.id", "file://"); // path to the html file.
user_pref("capability.principal.codebase.p0.subjectName", "");
下面是代码:
var File = function(file) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var ios = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
if (!File.baseURI) {
File.baseURI = ios.newURI(location.href.substring(0, location.href.lastIndexOf('/')+1), null, null);
File.baseFolder = File.baseURI.QueryInterface(Components.interfaces.nsIFileURL).file.path;
}
var URL = ios.newURI(file, null, File.baseURI);
this.fptr = URL.QueryInterface(Components.interfaces.nsIFileURL).file;
}
File.prototype = {
write: function(data) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
.createInstance(Components.interfaces.nsIFileOutputStream);
foStream.init(this.fptr, 0x02 | 0x08 | 0x20, 0666, 0);
var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"]
.createInstance(Components.interfaces.nsIConverterOutputStream);
converter.init(foStream, null, 0, 0);
converter.writeString(data);
converter.close();
},
read: function() {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"]
.createInstance(Components.interfaces.nsIFileInputStream);
var cstream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(Components.interfaces.nsIConverterInputStream);
fstream.init(this.fptr, -1, 0, 0);
cstream.init(fstream, null, 0, 0);
var data = "";
// let (str = {}) { // use this only when using javascript 1.8
var str = {};
cstream.readString(0xffffffff, str);
data = str.value;
// }
cstream.close();
return data;
}
};
据我所知,文件的内容完全在您的控制之下,而不必是特定的格式? 你只需要一种阅读的方式 您可以声明一个全局函数“handleFile”。 在外部文件中,内容必须如下所示:
handleFile('Mark Rodgers,mark.rodgers@company.com,Accounting');
要“读取”文件,只需添加一个具有相应src属性的脚本元素。
在函数“handleFile”中,您可以得到您的内容
文件的位置最初可能必须由用户设置,但之后您可以将位置保存在localStorage或类似的内容中。下面是一个在本地或服务器上工作的外部文件中使用JSON数据的示例。本例仅使用浏览器的语言设置加载带有本地化html的