简体   繁体   English

如何在浏览器中读取本地文本文件?

[英]How to read a local text file in the browser?

I'm trying to implemennt a simple text file reader by creating a function that takes in the file's path and converts each line of text into a char array, but it's not working.我试图通过创建一个 function 来实现一个简单的文本文件阅读器,它接受文件的路径并将每行文本转换为一个字符数组,但它不起作用。

function readTextFile() {
  var rawFile = new XMLHttpRequest();
  rawFile.open("GET", "testing.txt", true);
  rawFile.onreadystatechange = function() {
    if (rawFile.readyState === 4) {
      var allText = rawFile.responseText;
      document.getElementById("textSection").innerHTML = allText;
    }
  }
  rawFile.send();
}

What is going wrong here?这里出了什么问题?

This still doesn't seem to work after changing the code a little bit from a previous revision and now it's giving me an XMLHttpRequest exception 101.在从以前的版本稍微更改代码后,这似乎仍然不起作用,现在它给了我一个XMLHttpRequest异常 101。

I've tested this on Firefox and it works, but in Google Chrome it just won't work and it keeps giving me an Exception 101. How can I get this to work on not just Firefox, but also on other browsers (especially Chrome)?我已经在 Firefox 上测试过它并且它有效,但在 Google Chrome 中它不起作用并且它一直给我一个异常 101。我怎样才能让它不仅在 Firefox 上工作,而且在其他浏览器(尤其是 Chrome)上工作)?

You need to check for status 0 (as when loading files locally with XMLHttpRequest , you don't get a status returned because it's not from a Webserver )您需要检查状态 0(当使用XMLHttpRequest在本地加载文件时,您不会得到返回的状态,因为它不是来自Webserver

function readTextFile(file)
{
    var rawFile = new XMLHttpRequest();
    rawFile.open("GET", file, false);
    rawFile.onreadystatechange = function ()
    {
        if(rawFile.readyState === 4)
        {
            if(rawFile.status === 200 || rawFile.status == 0)
            {
                var allText = rawFile.responseText;
                alert(allText);
            }
        }
    }
    rawFile.send(null);
}

And specify file:// in your filename:并在文件名中指定file://

readTextFile("file:///C:/your/path/to/file.txt");

After the introduction of fetch api in javascript, reading file contents could not be simpler.在 javascript 中引入fetch api后,读取文件内容再简单不过了。

reading a text file读取文本文件

fetch('file.txt')
  .then(response => response.text())
  .then(text => console.log(text))
  // outputs the content of the text file

reading a json file读取一个 json 文件

fetch('file.json')
  .then(response => response.json())
  .then(jsonResponse => console.log(jsonResponse))     
   // outputs a javascript object from the parsed json

Update 30/07/2018 (disclaimer): 2018 年 7 月 30 日更新(免责声明):

This technique works fine in Firefox , but it seems like Chrome 's fetch implementation does not support file:/// URL scheme at the date of writing this update (tested in Chrome 68).这种技术能正常工作在Firefox,但它似乎是Chromefetch实现不支持file:/// URL方案在写这篇更新(在Chrome 68测试)的日期。

Update-2 (disclaimer):更新 2(免责声明):

This technique does not work with Firefox above version 68 (Jul 9, 2019) for the same (security) reason as Chrome: CORS request not HTTP .由于与 Chrome 相同的(安全)原因,此技术不适用于 68 版(2019 年 7 月 9 日)以上的FirefoxCORS request not HTTP See https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSRequestNotHttp .请参阅https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSRequestNotHttp

Visit Javascripture !访问Javascripture And go the section readAsText and try the example.并转到readAsText部分并尝试该示例。 You will be able to know how the readAsText function of FileReader works.您将能够知道FileReaderreadAsText函数是如何工作的。

    <html>
    <head>
    <script>
      var openFile = function(event) {
        var input = event.target;

        var reader = new FileReader();
        reader.onload = function(){
          var text = reader.result;
          var node = document.getElementById('output');
          node.innerText = text;
          console.log(reader.result.substring(0, 200));
        };
        reader.readAsText(input.files[0]);
      };
    </script>
    </head>
    <body>
    <input type='file' accept='text/plain' onchange='openFile(event)'><br>
    <div id='output'>
    ...
    </div>
    </body>
    </html>

 var input = document.getElementById("myFile"); var output = document.getElementById("output"); input.addEventListener("change", function () { if (this.files && this.files[0]) { var myFile = this.files[0]; var reader = new FileReader(); reader.addEventListener('load', function (e) { output.textContent = e.target.result; }); reader.readAsBinaryString(myFile); } });
 <input type="file" id="myFile"> <hr> <textarea style="width:500px;height: 400px" id="output"></textarea>

Yes JS can read local files (see FileReader()) but not automatically: the user has to pass the file or a list of files to the script with an html <input type="file"> .是的,JS 可以读取本地文件(参见 FileReader()),但不能自动读取:用户必须使用 html <input type="file">将文件或文件列表传递给脚本。

Then with JS it is possible to process (example view) the file or the list of files, some of their properties and the file or files content.然后使用 JS 可以处理(示例视图)文件或文件列表、它们的一些属性以及文件或文件内容。

What JS cannot do for security reasons is to access automatically (without the user input) to the filesystem of his computer.出于安全原因,JS 不能做的是自动(无需用户输入)访问他计算机的文件系统。

To allow JS to access to the local fs automatically is needed to create not an html file with JS inside it but an hta document.要让 JS 自动访问本地 fs,需要创建的不是其中包含 JS 的 html 文件,而是一个 hta 文档。

An hta file can contain JS or VBS inside it. hta 文件中可以包含 JS 或 VBS。

But the hta executable will work on windows systems only.但是 hta 可执行文件只能在 Windows 系统上运行。

This is standard browser behavior.这是标准的浏览器行为。

Also Google Chrome worked at the fs API, more info here: http://www.html5rocks.com/en/tutorials/file/filesystem/ Google Chrome 也在 fs API 工作,更多信息在这里: http : //www.html5rocks.com/en/tutorials/file/filesystem/

Modern solution:现代解决方案:

Use fileOrBlob.text() as follows:使用fileOrBlob.text()如下:

<input type="file" onchange="this.files[0].text().then(t => console.log(t))">

When user uploads a text file via that input, it will be logged to the console.当用户通过该输入上传文本文件时,它将被记录到控制台。 Here's a working jsbin demo .这是一个有效的 jsbin 演示

Here's a more verbose version:这是一个更详细的版本:

<input type="file" onchange="loadFile(this.files[0])">
<script>
  async function loadFile(file) {
    let text = await file.text();
    console.log(text);
  }
</script>

Currently (January 2020) this only works in Chrome and Firefox, check here for compatibility if you're reading this in the future: https://developer.mozilla.org/en-US/docs/Web/API/Blob/text目前(2020 年 1 月)这仅适用于 Chrome 和 Firefox,如果您将来阅读此内容,请在此处查看兼容性: https : //developer.mozilla.org/en-US/docs/Web/API/Blob/text

On older browsers, this should work:在较旧的浏览器上,这应该可以工作:

<input type="file" onchange="loadFile(this.files[0])">
<script>
  async function loadFile(file) {
    let text = await (new Response(file)).text();
    console.log(text);
  }
</script>

Related: As of September 2020 the new Native File System API available in Chrome and Edge in case you want permanent read-access (and even write access) to the user-selected file.相关:截至 2020 年 9 月,Chrome 和 Edge 中提供了新的本机文件系统 API ,以防您希望对用户选择的文件进行永久读取访问(甚至写入访问)。

Try creating two functions:尝试创建两个函数:

function getData(){       //this will read file and send information to other function
       var xmlhttp;

       if (window.XMLHttpRequest) {
           xmlhttp = new XMLHttpRequest();               
       }           
       else {               
           xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");               
       }

       xmlhttp.onreadystatechange = function () {               
           if (xmlhttp.readyState == 4) {                   
             var lines = xmlhttp.responseText;    //*here we get all lines from text file*

             intoArray(lines);     *//here we call function with parameter "lines*"                   
           }               
       }

       xmlhttp.open("GET", "motsim1.txt", true);
       xmlhttp.send();    
}

function intoArray (lines) {
   // splitting all text data into array "\n" is splitting data from each new line
   //and saving each new line as each element*

   var lineArr = lines.split('\n'); 

   //just to check if it works output lineArr[index] as below
   document.write(lineArr[2]);         
   document.write(lineArr[3]);
}

可以证明你已经尝试过了,输入“false”如下:

 rawFile.open("GET", file, false);

Using Fetch and async function使用Fetch和 async 函数

const logFileText = async file => {
    const response = await fetch(file)
    const text = await response.text()
    console.log(text)
}

logFileText('file.txt')

other example - my reader with FileReader class其他示例-我的带有 FileReader 类的阅读器

<html>
    <head>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css">
        <script src="http://code.jquery.com/jquery-1.10.2.js"></script>
        <script src="http://code.jquery.com/ui/1.11.3/jquery-ui.js"></script>
    </head>
    <body>
        <script>
            function PreviewText() {
            var oFReader = new FileReader();
            oFReader.readAsDataURL(document.getElementById("uploadText").files[0]);
            oFReader.onload = function (oFREvent) {
                document.getElementById("uploadTextValue").value = oFREvent.target.result; 
                document.getElementById("obj").data = oFREvent.target.result;
            };
        };
        jQuery(document).ready(function(){
            $('#viewSource').click(function ()
            {
                var text = $('#uploadTextValue').val();
                alert(text);
                //here ajax
            });
        });
        </script>
        <object width="100%" height="400" data="" id="obj"></object>
        <div>
            <input type="hidden" id="uploadTextValue" name="uploadTextValue" value="" />
            <input id="uploadText" style="width:120px" type="file" size="10"  onchange="PreviewText();" />
        </div>
        <a href="#" id="viewSource">Source file</a>
    </body>
</html>

This might help,这可能会有所帮助,

    var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");

    xmlhttp.onreadystatechange = function () {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            alert(xmlhttp.responseText);
        }
    }

    xmlhttp.open("GET", "sample.txt", true);
    xmlhttp.send();

Local AJAX calls in Chrome are not supported due to same-origin-policy.由于同源策略,不支持 Chrome 中的本地 AJAX 调用。

Error message on chrome is like this: "Cross origin requests are not supported for protocol schemes: http, data, chrome, chrome-extension, https." chrome 上的错误消息是这样的:“协议方案不支持跨源请求:http、data、chrome、chrome-extension、https。”

This means that chrome creates a virtual disk for every domain to keep the files served by the domain using http/https protocols.这意味着 chrome 会为每个域创建一个虚拟磁盘,以保存该域使用 http/https 协议提供的文件。 Any access to files outside this virtual disk are restricted under same origin policy.对该虚拟磁盘之外的文件的任何访问都受到同源策略的限制。 AJAX requests and responses happen on http/https, therefore wont work for local files. AJAX 请求和响应发生在 http/https 上,因此不适用于本地文件。

Firefox does not put such restriction, therefore your code will work happily on the Firefox. Firefox 没有这样的限制,因此您的代码可以在 Firefox 上正常运行。 However there are workarounds for chrome too : see here .但是也有针对 chrome 的解决方法:请参见此处

Adding to some the above answers, this modified solution worked for me.除了上面的一些答案,这个修改后的解决方案对我有用。

<input id="file-upload-input" type="file" class="form-control" accept="*" />

.... ……

let fileInput  = document.getElementById('file-upload-input');
let files = fileInput.files;

//Use createObjectURL, this should address any CORS issues.
let filePath = URL.createObjectURL(files[0]);

.... ……

function readTextFile(filePath){
    var rawFile = new XMLHttpRequest();
    rawFile.open("GET", filePath , true);
    rawFile.send(null);

    rawFile.onreadystatechange = function (){
        if(rawFile.readyState === 4){
            if(rawFile.status === 200 || rawFile.status == 0){
                var allText = rawFile.responseText;
                console.log(allText);
            }
        }
    }     
}
function readTextFile(file) {
    var rawFile = new XMLHttpRequest(); // XMLHttpRequest (often abbreviated as XHR) is a browser object accessible in JavaScript that provides data in XML, JSON, but also HTML format, or even a simple text using HTTP requests.
    rawFile.open("GET", file, false); // open with method GET the file with the link file ,  false (synchronous)
    rawFile.onreadystatechange = function ()
    {
        if(rawFile.readyState === 4) // readyState = 4: request finished and response is ready
        {
            if(rawFile.status === 200) // status 200: "OK"
            {
                var allText = rawFile.responseText; //  Returns the response data as a string
                console.log(allText); // display text on the console
            }
        }
    }
    rawFile.send(null); //Sends the request to the server Used for GET requests with param null
}

readTextFile("text.txt"); //<= Call function ===== don't need "file:///..." just the path 

- read file text from javascript - 从 javascript 读取文件文本
- Console log text from file using javascript - 使用 javascript 来自文件的控制台日志文本
- Google chrome and mozilla firefox - 谷歌浏览器和 Mozilla Firefox

in my case i have this structure of files :就我而言,我有这种文件结构: 在此处输入图像描述

the console.log result : console.log 结果:
在此处输入图像描述

<html>
<head>
    <title></title>
    <meta charset="utf-8" />
    <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
    <script type="text/javascript">
        $(document).ready(function () {            
                $.ajax({`enter code here`
                    url: "TextFile.txt",
                    dataType: "text",
                    success: function (data) {                 
                            var text = $('#newCheckText').val();
                            var str = data;
                            var str_array = str.split('\n');
                            for (var i = 0; i < str_array.length; i++) {
                                // Trim the excess whitespace.
                                str_array[i] = str_array[i].replace(/^\s*/, "").replace(/\s*$/, "");
                                // Add additional code here, such as:
                                alert(str_array[i]);
                                $('#checkboxes').append('<input type="checkbox"  class="checkBoxClass" /> ' + str_array[i] + '<br />');
                            }
                    }                   
                });
                $("#ckbCheckAll").click(function () {
                    $(".checkBoxClass").prop('checked', $(this).prop('checked'));
                });
        });
    </script>
</head>
<body>
    <div id="checkboxes">
        <input type="checkbox" id="ckbCheckAll" class="checkBoxClass"/> Select All<br />        
    </div>
</body>
</html>

Get local file data in js(data.js) load:在 js(data.js) 加载中获取本地文件数据:

function loadMyFile(){
    console.log("ut:"+unixTimeSec());
    loadScript("data.js?"+unixTimeSec(), loadParse);
}
function loadParse(){
    var mA_=mSdata.split("\n");
    console.log(mA_.length);
}
function loadScript(url, callback){

    var script = document.createElement("script")
    script.type = "text/javascript";

    if (script.readyState){  //IE
        script.onreadystatechange = function(){
            if (script.readyState == "loaded" ||
                    script.readyState == "complete"){
                script.onreadystatechange = null;
                callback();
            }
        };
    } else {  //Others
        script.onload = function(){
            callback();
        };
    }

    script.src = url;
    document.getElementsByTagName("head")[0].appendChild(script);
}
function hereDoc(f) {
  return f.toString().
      replace(/^[^\/]+\/\*![^\r\n]*[\r\n]*/, "").
      replace(/[\r\n][^\r\n]*\*\/[^\/]+$/, "");
}
function unixTimeSec(){
    return Math.round( (new Date()).getTime()/1000);
}

file of data.js like: data.js 文件,如:

var mSdata = hereDoc(function() {/*!
17,399
1237,399
BLAHBLAH
BLAHBLAH
155,82
194,376
*/});

dynamic unixTime queryString prevents cached.动态 unixTime queryString 防止缓存。

AJ works in web http://. AJ 在 web http:// 中工作。

If you want to prompt the user to select a file, then read its contents:如果要提示用户选择文件,则读取其内容:

// read the contents of a file input
const readInputFile = (inputElement, callback) => {
  const reader = new FileReader();
  reader.onload = () => {
    callback(reader.result)
  };
  reader.readAsText(inputElement.files[0]);
};
// create a file input and destroy it after reading it
export const openFile = (callback) => {
  var el = document.createElement('input');
  el.setAttribute('type', 'file');
  el.style.display = 'none';
  document.body.appendChild(el);
  el.onchange = () => {readInputFile(el, (data) => {
    callback(data)
    document.body.removeChild(el);
  })}
  el.click();
}

Usage:用法:

// prompt the user to select a file and read it
openFile(data => {
    console.log(data)
  })

This is an old question but there two main ideas that we have to be clear.这是一个老问题,但我们必须弄清楚两个主要观点。 Do we want to read the whole file or get it line by line?我们是要读取整个文件还是逐行获取?

Teo, I want to get the whole file and process it later. Teo,我想获取整个文件并稍后处理。

Okay that is very easy we just call text (remember that text assumes that the file is encoded as UTF-8 ) and handle the file like this:好的,这非常简单,我们只需调用text (记住text假定文件编码为UTF-8 )并像这样处理文件:

 const $output = document.getElementById('output') const $file = document.getElementById('file') const fetchFile = async e => { const [file] = e.target.files const text = await file.text() $output.textContent = text } $file.onchange = fetchFile
 <input id='file' type='file' accept='text/plain'><br> <pre id='output'>...</pre>

What about line by line?一行一行呢? It is possible?.有可能的?。

Well my young Padawan, that is also possible we just need a split the text in lines like this好吧,我年轻的 Padawan,这也是可能的,我们只需要像这样将文本split几行

 const $output = document.getElementById('output') const $file = document.getElementById('file') let count const fetchFile = async e => { const [file] = e.target.files if (.file) return count = 0 const text = await file.text() $output.textContent = text const lines = text?split(/\r.\n/gm) for (const line of lines) { if (line) count++ } console.log({count}) } $file.onchange = fetchFile
 <input id='file' type='file' accept='text/plain'><br> <pre id='output'>...</pre>

You can import my library:您可以导入我的库:

 <script src="https://www.editeyusercontent.com/preview/1c_hhRGD3bhwOtWwfBD8QofW9rD3T1kbe/code.js?pe=yikuansun2015@gmail.com"></script>

then, the function fetchfile(path) will return the uploaded file然后,函数fetchfile(path)将返回上传的文件

 <script src="https://www.editeyusercontent.com/preview/1c_hhRGD3bhwOtWwfBD8QofW9rD3T1kbe/code.js"></script> <script>console.log(fetchfile("file.txt"))</script>

Please note: on Google Chrome if the HTML code is local, errors will appear, but saving the HTML code and the files online then running the online HTML file works.请注意:在谷歌浏览器上,如果 HTML 代码是本地的,则会出现错误,但在线保存 HTML 代码和文件然后运行在线 HTML 文件是可行的。

In order to read a local file text through JavaScript using chrome, the chrome browser should run with the argument --allow-file-access-from-files to allow JavaScript to access local file, then you can read it using XmlHttpRequest like the following:为了使用 chrome 通过JavaScript读取本地文件文本,chrome 浏览器应该运行参数--allow-file-access-from-files以允许 JavaScript 访问本地文件,然后您可以使用XmlHttpRequest读取它,如下所示:

var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
   if (xmlhttp.readyState == 4) {
       var allText = xmlhttp.responseText;          
            }
        };
xmlhttp.open("GET", file, false);
xmlhttp.send(null);

How to read a local file?如何读取本地文件?

By using this you will load a file by loadText() then JS will asynchronously wait until the file is read and loaded after that it will execture readText() function allowing you to continue with your normal JS logic (you can also write a try catch block on the loadText() function in the case any error arises) but for this example I keep it at minimal.通过使用它,您将通过 loadText() 加载文件,然后 JS 将异步等待文件被读取并加载,之后它将执行 readText() 函数,允许您继续正常的 JS 逻辑(您也可以编写 try catch在出现任何错误的情况下阻塞 loadText() 函数),但对于这个示例,我将其保持在最低限度。

async function loadText(url) {
    text = await fetch(url);
    //awaits for text.text() prop 
    //and then sends it to readText()
    readText(await text.text());
}

function readText(text){
    //here you can continue with your JS normal logic
    console.log(text);
}

loadText('test.txt');

I know, I am late at this party.我知道,我在这个聚会上迟到了。 Let me show you what I have got.让我告诉你我有什么。

This is a simple reading of text file这是一个简单的文本文件读取

var path = "C:\\path\\filename.txt"
var fs = require('fs')
fs.readFile(path , 'utf8', function(err, data) {
  if (err) throw err;
  console.log('OK: ' + filename);
  console.log(data)
});

I hope this helps.我希望这有帮助。

This function made for browsers and open file picker dialog and after user selection read file as binary and call callback function with read data:此函数适用于浏览器和打开文件选择器对话框,在用户选择读取文件作为二进制文件并使用读取数据调用回调函数后:

function pickAndReadFile(callback) {
    var el = document.createElement('input');
    el.setAttribute('type', 'file');
    el.style.display = 'none';
    document.body.appendChild(el);
    el.onchange = function (){
        const reader = new FileReader();
        reader.onload = function () {
            callback(reader.result);
            document.body.removeChild(el);
        };
        reader.readAsBinaryString(el.files[0]);
    }
    el.click();
}

And use it like this:并像这样使用它:

pickAndReadFile(data => {
  console.log(data)
})

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

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