如何加载一个txt/csv文件到javascript字符串/数组,而离线

How to load a txt/csv file into javascript string/array while offline

本文关键字:javascript 离线 字符串 数组 文件 txt 加载 何加载 一个 csv      更新时间:2023-09-26

我有一个小的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. 

我似乎不能让这些离线工作。我怎么才能做到呢?

编辑:

我设法让以下工作仅在Firefox上使用这里找到的CSVToArray函数,这是相当缓慢的这种大小的文件,和一个隐藏的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"'); 
            }
        }
    }

这可能在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>

您想要做什么并不十分清楚。

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

还有,关于Shota的帖子。除非有服务器在后台运行,否则不能使用AJAX。如果您决定在服务器上设置系统,那么有许多选项可以实现您想要的功能。

我的评论太长了

不能像包含媒体一样包含数据文件。最简单的方法是将csv预处理为js数组,然后像js <script src="mydata.csv.js"></script>一样包含csv。

你说的离线是指本地文件而不是公共文件?第一个建议是升级浏览器。如果它是一个支持所有主流浏览器的本地文件,那就没有意义了。抱歉,我相信你有理由不去。但是升级会绕过ie8对非Ecmascript 5的支持。

要绕过跨源策略,您必须在本地web服务器上运行文件。所以你的html页面会在localhost:8080和你的csv localhost:8080/mydata.csv这给了html特权,允许访问csv文件,因为他们现在在同一个域。D3, jquerycsv现在应该工作。允许任何html文件自由访问文件系统是一个很大的安全风险。

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

选择文件后,要读取主浏览器(使用Ecma5)的内容,请查看MDN上的FileReader,可以在这里找到一个使用示例。ie8 + 9支持VBscript读取文件。你可以像使用JS一样使用VB使用<script type="text/vbscript"></script>

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

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

:

  • https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage
  • https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe

您已经意识到,任何基于ajax的解决方案都会受到本地文件访问的安全限制的影响。与寻找特定于浏览器的解决方案不同,您可以使用JSONP方法,从而避免使用AJAX。

这将要求您预处理CSV数据,并将其保存为更适合js的格式。但无论如何,这将是一个好主意,因为本机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"]
]);