简体   繁体   English

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

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

I have a small html/javascript webpage that I want to run in a browser offline. 我有一个小的html / javascript网页,我想在浏览器中离线运行。

In the same way the page can include an image or a css file and use it while offline, I want to include a 3mb spreadsheet that the javascript reads into a 2d-array, and I'm hoping for something that would work on IE8 as well as modern browsers. 以同样的方式页面可以包含图像或css文件并在离线时使用它,我想要包含一个3mb的电子表格,javascript读入2d数组,我希望有一些可以在IE8上工作的东西以及现代浏览器。

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

I've found multiple methods online like 我在网上发现了多种方法

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

or 要么

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

or 要么

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

But I tend to get same-origin policy errors such as: 但我倾向于得到同源政策错误,例如:

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. 

I can't seem to get these to work offline. 我似乎无法让这些离线工作。 How could I accomplish this? 我怎么能做到这一点?

Edit: 编辑:

I'm managed to get the following to work for a text file only on Firefox using the CSVToArray function found here , which is pretty sluggish with a file of this size, and a hidden iframe . 我设法使用此处的CSVToArray函数在Firefox上使用以下文本文件来处理文本文件,这个文件非常缓慢,并且隐藏了iframe

Ultimately, it would be preferable if this was capable of running on IE8, and if I used a csv rather than a txt file, but at least it's a start. 最终,如果能够在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); 
}

For IE8 I managed to get this to work on a small scale but with the 3mb file it will occasionally crash the browser and will always accost the user with both a ton of warning messages that activex is being used and a wave of warnings that the script will slow down the computer. 对于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"'); 
            }
        }
    }

This might not work in IE8, but the HTML5 API is really useful for this. 这在IE8中可能不起作用,但HTML5 API对此非常有用。 Just use: 只需使用:

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."
        }
    });    
}

Then after that, a simple .html file that looks like this would do the trick: 然后,一个看起来像这样的简单的.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>

It's not quite clear what you want to do. 目前还不清楚你想做什么。

Using jQuery it's possible to modify events that happen in the DOM. 使用jQuery可以修改DOM中发生的事件。 Using this you could potentially save the source code when you're done making changes. 使用此功能,您可以在完成更改后保存源代码。 You would then need to replace your current source code with the saved code to use the changes the next time you open up the page. 然后,您需要使用保存的代码替换当前源代码,以便在下次打开页面时使用更改。 However, this would be a very laborious process and there are likely a number of better ways to accomplish what you want to do depending on what that is. 然而,这将是一个非常费力的过程,并且可能有许多更好的方法来完成你想做的事情,具体取决于它是什么。

Also, in regards to Shota's post. 此外,关于Shota的帖子。 You can't use AJAX unless you have a server running in the background. 除非您在后台运行服务器,否则无法使用AJAX。 If you decide to set the system up on a server there are a number of options for accomplishing what you want. 如果您决定在服务器上设置系统,则可以使用许多选项来完成您想要的操作。

As you have realized, any AJAX-based solution will be affected by security restrictions for local file access. 如您所知,任何基于AJAX的解决方案都会受到本地文件访问的安全限制的影响。 Instead of finding browser-specific workarounds, you could go the JSONP way which avoids AJAX. 您可以采用JSONP方式避免使用AJAX,而不是找到特定于浏览器的解决方法。

This would require you to pre-process your CSV data and save it in a more JS-friendly format . 这将要求您预处理CSV数据并以更加JS友好的格式保存 But this would be a good idea anyway, as native JS parsing is likely to perform better than a CSV parser implemented in JS. 但无论如何这都是一个好主意,因为本机JS解析可能比JS中实现的CSV解析器表现更好。

It could look roughly like this: 它看起来大致如下:

index.html 的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 的script.js

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

data.js data.js

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

My comment become too long. 我的评论太长了。

You can't include data files in the same way as media. 您不能以与媒体相同的方式包含数据文件。 The easiest way would be to preprocess the csv into a js array and then include the csv like js <script src="mydata.csv.js"></script> . 最简单的方法是将csv预处理为js数组,然后包含csv,如js <script src="mydata.csv.js"></script>

By offline you mean local files and not public? 离线你的意思是本地文件而不是公开? The first suggestion would be to upgrade your browser. 第一个建议是升级您的浏览器。 It doesn't quiet make sense if its a local file supporting all major browsers. 如果它是支持所有主流浏览器的本地文件,那么它就没有意义。 Sorry I'm sure you have reasons why you can't. 对不起,我相信你有理由不能。 But upgrading would get around the non Ecmascript 5 support in ie8. 但升级将绕过ie8的非Ecmascript 5支持。

To get around the cross origin policy you'd have to run your file on a local webserver. 要绕过跨源策略,您必须在本地Web服务器上运行您的文件。 So your html page would be on something like localhost:8080 and your csv localhost:8080/mydata.csv this gives privileges to the html to allow access to the csv file as they're now on the same domain. 因此,您的html页面将类似于localhost:8080和您的csv localhost:8080 / mydata.csv这为html提供了权限,允许访问csv文件,因为它们现在位于同一个域中。 D3, jquerycsv should now work. D3,jquerycsv现在应该可以工作了。 Its a big security risk allowing any html file to access the filesystem freely. 它存在很大的安全风险,允许任何html文件自由访问文件系统。

If a local server isn't an option. 如果本地服务器不是一个选项。 You have to select the file each time you load with an input field. 每次加载输入字段时都必须选择文件。 This grants the browser permissions to access this file. 这将授予浏览器访问此文件的权限。

After selecting the file, to read the contents for the main browsers (with Ecma5) look into FileReader on MDN , and an example of use can be found here . 选择文件后,要读取主浏览器的内容(使用Ecma5),请查看MDN上的FileReader此处可以找到使用示例。 For ie8 + 9 there is VBscript support to read files. 对于ie8 + 9,有VBscript支持读取文件。 You can use VB just like JS using <script type="text/vbscript"></script> 你可以像使用<script type="text/vbscript"></script>一样使用VB

If you really want to access local resources from a sever page then you need also a local page that allows the access. 如果您确实想要从服务器页面访问本地资源,那么您还需要一个允许访问的本地页面。 A local HTML page inside an <iframe> could read the text file and post contents to the main page via window.postMessage() . <iframe>本地HTML页面可以通过window.postMessage()读取文本文件并将内容发布到主页面。

There might also be a way with HTML5 iframes and the sandbox attribute, but not in IE9 and below. 可能还有一种方法可以使用HTML5 iframe和sandbox属性,但不能在IE9及更低版本中使用。

see: 看到:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM