在JavaScript中使用本地文件作为数据源 [英] Using a local file as a data source in JavaScript

查看:126
本文介绍了在JavaScript中使用本地文件作为数据源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想制作一个仅使用JavaScript / HTML 的应用,并且可以由浏览器直接从文件系统打开。这个应用必须能够从另一个文件读取数据。然后我将使用JS来解析它并呈现页面。作为简化示例,假设我有一个CSV文件(此处下载)

  Mark Rodgers,mark.rodgers @ company.com,会计
[...]
Melissa Jones,melissa @ company.com,CEO

我希望能够使用JS读取文件,并使用它中的数据生成我的页面。



到目前为止所取得的成绩:

演示 (右键单击 - >另存为将HTML保存到您的计算机)。它也可以 jsfiddle 以半破解方式使用(布局已损坏,但它仍应功能正确)。



只需将CSV文本文件拖放到拖放框中,或使用文件菜单选择文本文件,JavaScript将读取,解析文件并填充表。



这依赖于FileReader API;大部分繁重的工作都是通过这个函数完成的:

  function handleFileSelect(evt){
evt.stopPropagation() ;
evt.preventDefault();

var files = evt.target.files || evt.dataTransfer.files; // FileList对象
var file = files [0];

//这会创建FileReader并以文本形式读取内容
var fr = new FileReader();
fr.onload = parse;
fr.readAsText(file);

//这是实际解析文件
//的函数并填充表
函数解析()
{
var table = document .getElementById( '的emps');
var employees = fr.result.split('\\\
'); var c = 0;
for(员工中的var i)
{
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>从文件中添加'+ c +'员工:'+ file.name +'< /跨度>';


这几乎是 OK ,但它不方便用户手动加载文件。理想情况下,它应该能够自动加载它,但出于安全原因,没有浏览器会允许......尚未。



解决方案要求:




  • 必须离线工作;即:它不能依赖任何在线服务。这还包括在本地计算机上运行的HTTP服务器。只需安装浏览器即可在任何计算机上运行。

  • 使用文件打开页面时必须工作:/// 协议(即:硬盘上的HTML页面)。 不应该依赖第三方附加组件(例如:Flash,Java, shudders 。我敢肯定,如果页面位于 file:///


  • 它必须能够接受任意数据。这就排除了以一种行为良好的格式加载文件,该文件已经准备好像JSON一样使用
  • 如果它可以在任何一个(理想情况下都是) Firefox或Chrome很好。依赖实验性API也是可以的




我事先知道文件名是什么,所以可以编码HTML本身。 使我能够从磁盘读取文件的任何解决方案都很好,它不必使用FileReader API。



所以,如果有的话一个聪明的黑客将文件加载到一个很好的页面(也许加载到一个不可见的iframe并让JS检索内容);那也没关系。

解决方案

以下是在本地或服务器上运行的外部文件中使用JSON数据的示例。这个例子只是使用浏览器的语言设置来加载一个< script>用本地化的html,然后处理它的json对象,以重置本地化内容中指定标签中的数据

 < html> < meta http-equiv =Content-Typecontent =text / html; charset = utf-8> 
< head>
< script>
函数setLang(){
for(var i = 0; i< items.length; i ++){
term = document.getElementById(items [i] .id)
if(term)term.innerHTML = items [i] .value
}
}
var lang = navigator.userLanguage || navigator.language;
var script = document.createElement(script);
script.src = document.URL + - + lang.substring(0,2)+。js
var head = document.getElementsByTagName('head')[0]
head.insertBefore(script,head.firstChild)
< / script>
< / head>
< body onload ='setLang()'>
< div id =string1class =txt>这是string1的默认文本。< / div>
< div id =string2class =txt>这是string2的默认文本。< / div>
< / body>< / html>

数据文件的格式如下:

< pre $ items = [
{id:string1,value:string1的本地化文本。},
{id: string2,value:string2的本地化文本。}
];

但您可以使用任何参数来有条件地加载相应的文件(它将作为第一个标签插入在< head>中,所以它可以在任何地方使用)并且JSON格式能够处理大量的数据。你可能想要将函数setLang重命名为更合适的东西,并修改它以满足你的需要,例如...为每个我添加一行,然后添加带有数据的字段(看起来你已经有了该部分的句柄)你的JSON应该是这样的:

  items = [
{fname:john,lname :smith,address:1 1st St,phone:555-1212},
{fname:jane,lname:smith :1 1st St,phone:555-1212}
];如果你需要预处理你的数据,awk非常方便 - 它会是这样的:(未经测试) )

  awk'BEGIN {FS =,; printitems = [\\\
}
{printf{\fname \:\%s \,\lname \:\smith \,\add​​ress \:\1 1st St \,\phone\:\555-1212 \},\\\
,$ 1,$ 2,$ 3,$ 4}
END {print];}' file.csv> file.js

编辑:现在OP更清晰了,只有mozilla浏览器允许XMLHttpRequest在文件上:/ /开箱即用,Chrome(可能还有其他基于webkit的浏览器)可以配置为允许它。知道它可能不适用于IE< 10,你可以:

  var filePath =your_file 。文本; 
xmlhttp = new XMLHttpRequest();
xmlhttp.open(GET,filePath,false);
xmlhttp.overrideMimeType('text / plain');
xmlhttp.send(null);
//可能检查状态!= 404 here
var fileContent = xmlhttp.responseText;
var fileArray = fileContent.split('\ n')
var n = fileArray.length;
//从这里处理你的数据可能再次使用split为','

为其他可能有类似问题的人留下最初的json-p变体,但对其数据格式有一定的控制权,因为它适用于所有支持javascript的浏览器。但是,如果有人知道如何使其适用于IE(除了运行小型Web服务器),请编辑。



编辑2:



使用mozilla浏览器,您还可以使用iframe

 < html> 
< meta http-equiv =Content-Typecontent =text / html; charset = utf-8>
< head>
< script>
函数showContents(frameObject){
alert(frameObject.contentDocument.body.innerHTML);
//替换为您的代码
}
< / script>
< / head>
< body onload ='showContents()'>
< iframe id =frametestsrc =data.txtonload =showContents(this);
style =visibility:hidden; display:none>< / iframe>
< / body>< / html>


Background:

I want to make an "app" that uses JavaScript/HTML only and can be opened by a browser directly from the filesystem. This app must be able to read data from another file. I'll then use JS to parse it and render pages. As a simplified example, imagine I have a CSV file (download here):

Mark Rodgers,mark.rodgers@company.com,Accounting
[...]
Melissa Jones,melissa@company.com,CEO

I want to be able to read the file using JS and use data in it to generate my page.

What I've accomplished so far:

Demo (right-click -> "Save As" to save HTML to your computer). It's also available on jsfiddle in semi-broken fashion (layout is broken, but it should still be functionally correct).

Simply drag and drop the CSV text file into the drag and drop box, or select the text file using the file menu, and JavaScript will read, parse the file and populate the table.

This relies on the FileReader API; most of the heavy lifting is done by this function:

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>';
    }
}

This is almost OK, but it inconveniences the user into manually loading a file. Ideally it should be able to load it automatically, but for security reasons no browser will allow that... yet.

Solution Requirements:

  • Must work offline; ie: it can't rely on any online service. This also includes HTTP servers running on the local machine. The idea is to have this run on any computer with just a browser installed.

  • Must work when the page is opened using the file:/// protocol (ie: a HTML page on the hard drive).

  • Should not rely on third party add ons (eg: Flash, Java, shudders ActiveX). I'm pretty sure these probably wouldn't work anyways if the page is in file:///

  • It must be able to accept arbitrary data. This rules out loading a file in a well-behaved format that's ready for consumption like JSON.

  • If it works on either (ideally both) Firefox or Chrome it's fine. It's also OK to rely on experimental APIs

I know what the file name is beforehand, so it could be coded in the HTML itself. Any solution that enables me to read a file from disk is fine, it doesn't have to use the FileReader API.

So if there's a clever hack to load a file into a page that's fine too (maybe load it into an invisible iframe and have JS retrieve the contents); that's OK too.

解决方案

Here is an example that uses JSON data in an external file that works locally or on a server. This example just uses the browser's language setting to load a < script > with localized html and then processes its json object to reset the data in the indicated tags with localized content

<html><meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<head>
<script>
    function setLang(){
        for (var i=0;i<items.length;i++){
            term=document.getElementById(items[i].id)
            if (term) term.innerHTML=items[i].value
        }
    }
    var lang=navigator.userLanguage || navigator.language;
    var script=document.createElement("script");
    script.src=document.URL+"-"+lang.substring(0,2)+".js"
    var head = document.getElementsByTagName('head')[0]
    head.insertBefore(script,head.firstChild)
</script>
</head>
<body onload='setLang()'>
<div id="string1" class="txt">This is the default text of string1.</div> 
<div id="string2" class="txt">This is the default text of string2.</div>
</body></html>

The data files for this look like:

items=[
{"id":"string1","value":"Localized text of string1."},
{"id":"string2", "value":"Localized text of string2."}
];

but you can use any parameter to conditionally load the appropriate file (it will be inserted as the first tag in < head >, so it will be usable in anywhere) and the JSON format is capable of handling a large variety of data. You may want to rename the function setLang to something more appropriate and modify it to meet your needs such as ... for each i add a row, then add fields with the data (it looks like you already have a handle on that part) and your JSON would look like:

items=[
{"fname":"john","lname":"smith","address":"1 1st St","phone":"555-1212"},
{"fname":"jane","lname":"smith","address":"1 1st St","phone":"555-1212"}
];

if you need to preprocess your data, awk is pretty handy - it would be something like: (untested guestimate)

awk 'BEGIN{FS=",";print "items=[\n"}
{printf "{\"fname\":\"%s\",\"lname\":\"smith\",\"address\":\"1 1st St\",\"phone\":\"555-1212\"},\n", $1, $2, $3, $4}
END{print "];"}' file.csv > file.js

Edit: now that OP is more clear, only mozilla browsers allow XMLHttpRequest on file:// out of the box and chrome (possibly other webkit based browsers) can be configured to allow it. Knowing that it may NOT work on IE<10, you can:

var filePath = "your_file.txt";
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET",filePath,false);
xmlhttp.overrideMimeType('text/plain');
xmlhttp.send(null);
//maybe check status !=404 here
var fileContent = xmlhttp.responseText;
var fileArray = fileContent.split('\n')
var n = fileArray.length;
//process your data from here probably using split again for ','

I'm leaving the initial json-p variation for others that may have a similar issue, but have some control of their data format, since it will work on all javascript capable browsers. However, if anyone knows a way to make it work for IE (other than running a small web server), please edit.

Edit 2:

With mozilla browsers you can also use iframes

<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<head>
<script>
function showContents(frameObject){
    alert(frameObject.contentDocument.body.innerHTML);
    //replace with your code
}
</script>
</head>
<body onload='showContents()'>
<iframe id="frametest" src="data.txt" onload="showContents(this);" 
    style="visibility:hidden;display:none"></iframe>
</body></html>

这篇关于在JavaScript中使用本地文件作为数据源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆