如何在脱机时将txt / csv文件加载到javascript字符串/数组中

时间:2014-06-21 21:27:15

标签: javascript arrays csv offline

我有一个小的html / javascript网页,我想在离线浏览器中运行。

以同样的方式,页面可以包含图像或css文件,并在离线时使用它,我想要包含一个3mb的电子表格,javascript读入2d阵列,我希望有一些东西,适用于IE8以及现代浏览器。

C:\Folder\index.html
C:\Folder\code.js
C:\Folder\picture.png
C:\Folder\spreadsheet.csv

我在网上找到了多种方法,如

<script src="jquery-csv.js"></script>
var table = $.csv.toArrays("spreadsheet.csv");

d3.text('spreadsheet.csv', function(error, _data){
            var table = d3.csv.parseRows(_data);
        });

$(document).ready(function() {
    $.ajax({
        type: "GET",
        url: "data.txt",
        dataType: "text",
        success: function(data) {processData(data);}
     });
});

但我倾向于得到同源政策错误,例如:

XMLHttpRequest cannot load file://data.txt. Received an invalid response. Origin 'null' is therefore not allowed access.

Uncaught SecurityError: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame with origin "null" from accessing a frame with origin "null". Protocols, domains, and ports must match. 

我似乎无法让这些离线工作。我怎么能做到这一点?

修改

我设法使用找到here的CSVToArray函数,仅在 Firefox 上获取以下文本文件,但这个文件非常缓慢,以及隐藏的iframe

最终,如果能够在IE8上运行,如果我使用的是csv而不是txt文件,那将是更好的选择,但至少它是一个开始。

<iframe style="display:none;" id='text' src = 'file.txt' onload='read_text_file()'>
</iframe>

<script type="text/javascript" >

function read_text_file() {
    var text = document.getElementById('text').contentDocument.body.firstChild.innerHTML;
    var table = CSVToArray(text); 
}

对于 IE8 我设法让这个小规模工作但是使用3mb文件它偶尔会崩溃浏览器并且总是会给用户带来大量的警告消息,即activex是被使用以及脚本会使计算机变慢的警告浪潮。

    window.onLoad = readFileInIE("file.csv");

    function readFileInIE(filePath) {

        try {
            var fso = new ActiveXObject("Scripting.FileSystemObject");      
            var file = fso.OpenTextFile(filePath, true);                                    
            var text = file.ReadAll();  
            var table = CSVToArray(text);
            file.Close();

            return fileContent;
        } catch (e) {
            if (e.number == -2146827859) {
                alert('Unable to access local files due to browser security settings. ' + 
                    'To overcome this, go to Tools->Internet Options->Security->Custom Level. ' + 
                    'Find the setting for "Initialize and script ActiveX controls not marked as safe" and change it to "Enable" or "Prompt"'); 
            }
        }
    }

5 个答案:

答案 0 :(得分:1)

这在IE8中可能不起作用,但HTML5 API对此非常有用。只需使用:

window.onload = function() {
    var fileInput = document.getElementById('fileInput');             

    fileInput.addEventListener('change', function(e) {
        var file = fileInput.files[0];
        var textType = //format you'd like to recieve;
        if (file.type.match(textType)) {
            var reader = new FileReader();              
            reader.onload = function(e) {
                // apply magic here
            }
            reader.readAsText(file);
        }
        else
        {
            fileDisplayArea.innerText ="Sorry matey, can't help you with that filetype."
        }
    });    
}

然后,一个看起来像这样的简单的.html文件就可以了:

<html lang="en">
    <head>        
        <script src="script.js"></script>          
    </head>
    <body>
        <div id="page-wrapper">
            <div> 
                <input type="file" id="fileInput">
            </div>
            <pre id="fileDisplayArea"></pre> //display any output here
        </div>
    </body>
</html>

答案 1 :(得分:0)

你不清楚自己想做什么。

使用jQuery可以修改DOM中发生的事件。使用此功能,您可以在完成更改后保存源代码。然后,您需要使用保存的代码替换当前源代码,以便在下次打开页面时使用更改。然而,这将是一个非常费力的过程,并且可能有许多更好的方法来完成你想做的事情,具体取决于它是什么。

另外,关于Shota的帖子。除非您在后台运行服务器,否则您无法使用AJAX。如果您决定在服务器上设置系统,则可以使用许多选项来完成您想要的操作。

答案 2 :(得分:0)

如您所知,任何基于AJAX的解决方案都会受到本地文件访问的安全限制的影响。您可以采用JSONP方式避免使用AJAX,而不是查找特定于浏览器的解决方法。

这需要您预处理CSV数据和save it in a more JS-friendly format。但无论如何这都是一个好主意,因为本机JS解析可能比JS中实现的CSV解析器表现更好。

它看起来大致如下:

<强>的index.html         

    </head>
    <body>
        <div id="page-wrapper">
        <div> 
            <input type="file" id="fileInput">
        </div>
        <pre id="fileDisplayArea"></pre> <!-- display any output here -->

        </div>
        <script src="script.js"></script>
        <script src="data.js"></script>
    </body>
</html>

<强>的script.js

function processData(data) {
    // Your logic
    // (will be called once data.js is loaded)
}

<强> data.js

processData([
    ["your", "data"]
]);

答案 3 :(得分:0)

我的评论太长了。

您不能以与媒体相同的方式包含数据文件。最简单的方法是将csv预处理为js数组,然后包含csv,如js <script src="mydata.csv.js"></script>

离线你是指本地文件而非公开?第一个建议是升级您的浏览器。如果它是支持所有主流浏览器的本地文件,它就没有意义。对不起,我确定你有理由不能这样做。但升级将绕过ie8的非Ecmascript 5支持。

要解决跨源策略,您必须在本地网络服务器上运行您的文件。因此,您的html页面将类似于localhost:8080和您的csv localhost:8080 / mydata.csv,这为html提供了权限,允许访问csv文件,因为它们现在位于同一个域中。 D3,jquerycsv现在应该可以工作了。它存在很大的安全风险,允许任何html文件自由访问文件系统。

如果本地服务器不是一个选项。每次加载输入字段时都必须选择文件。这将授予浏览器访问此文件的权限。

选择文件后,要阅读主浏览器的内容(使用Ecma5),请查看FileReader on MDN,并找到使用示例here。对于ie8 + 9,有VBscript support个读取文件。您可以像使用<script type="text/vbscript"></script>

的JS一样使用VB

答案 4 :(得分:0)

如果您确实想要从服务器页面访问本地资源,那么您还需要一个允许访问的本地页面。 <iframe>内的本地HTML页面可以读取文本文件,并通过window.postMessage()将内容发布到主页。

可能还有HTML5 iframe和sandbox属性的方法,但在IE9及以下版本中没有。

请参阅: