react中读取本地文件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了react中读取本地文件相关的知识,希望对你有一定的参考价值。

参考技术A <input type="file" id="file" onChange=this.jsReadFiles.bind(this)/>

//js 读取文件

React.js 从本地文件读取

【中文标题】React.js 从本地文件读取【英文标题】:React.js reading from a local file 【发布时间】:2019-11-22 06:07:21 【问题描述】:

我目前在我的应用程序中使用 node js 反应。

我正在尝试从文本文件中读取,当我尝试不同的事情时得到不同的错误。通过研究,从文件读取的最简单路径是使用“fs”,所以我将发布我尝试从本地文件(客户端)读取的两种方法。

如果有人能帮助我解决我的错误,我将不胜感激,甚至向我展示一种从本地文件读取的不同方式!

import React ...
import  readFile, readFileSync  from 'fs';
// other imports

class Background extends Component 
     // my constructor

     componentDidMount() 
         this.loadMe();
     

     loadMe() 
          var file = './read_file';

          /* WAY 1: Asynchronously using readFile */
          readFile(file, function(err, data) 
               if (err)  console.log(err) 
               console.log(data);
          

          /* WAY 2: Synchronously using readFileSync */
          var data = readFileSync(file);
          console.log(data);
     

显然,我不会同时运行两种方式。我还基本上从其他堆栈溢出答案和一些在线教程中复制了代码。我查看了FileReader,但无法正常工作。

我当前收到的错误:TypeError: Object(...) is not a function 指向 var data = readFileSync(file);

谢谢!

【问题讨论】:

我认为您正在混合从 node-js 和 React 中读取的知识。 React 不能使用 'fs' 因为 fs 如果是节点库。 React 在浏览器上运行,而不是在节点中,因此您需要使用 FileReader 和输入字段。如果每个网站都可以使用 fs 直接从客户端的磁盘读取,那将是一个可怕的安全漏洞!解决方案是创建一个“文件”类型的 字段(典型的“选择文件”按钮),然后使用 FileReader 读取文件。 是的,我对两者都比较陌生,所以我对它被混淆并不感到惊讶。感谢您的澄清,您是否建议在这种情况下使用 FileReader? 是的。我为你写了一个例子。查看我的回答,如果它解决了您的问题,请接受:) 【参考方案1】:

fs 是为服务器 JS 环境保留的库,如 NodeJS。

【讨论】:

该死的。我真的希望这个功能在客户端,而不是我的应用程序的服务器端。你知道从文件中读取数据的其他方法吗? 您可以使用 fetch/axios 之类的库加载公共文件夹中的文件,如果它们是静态的,则可以通过 webpack 通过相对 url 导入它 我可以试试,我唯一的问题是用户需要不时编辑文件。例如,单击按钮时,它会在文件中添加一个包含特定信息的新行。这还有可能吗? 不,仅靠前端是不可能的。您需要一个后端来管理文件系统的操作。 @MosèRaguzzini,你在误导......确实可以从客户端的文件中读取。只是没有'fs'。有时,错误的答案比没有答案更糟糕。【参考方案2】:

无法直接从浏览器打开和编辑文件。 但是,可以打开文件,编辑然后下载编辑后的文件。

你需要一个input 类型的input 元素,因为这样浏览器可以保证页面只访问用户明确选择的文件。 (如果 cmets 不清楚,请告诉我。如果不是,我会尽力解释得更好。)

在下面的示例中,我将使用 textarea 元素来编辑文件的内容,但您可以在代码中更改它,或者在字符串变量中包含内容后随意更改。

<!DOCTYPE html>
<html>
<head>
    <title>FileReader Example</title>
    <meta  charset="utf-8"/>
    <script>
        document.addEventListener('DOMContentLoaded',function() 
            var fileInput       = document.getElementById("fileInput");
            var textArea        = document.getElementById("fileEditor");
            var saveFileButton  = document.getElementById("saveFileButton");
            var downloadAnchor  = document.getElementById("downloadAnchor");

            function base64EncodeUnicode(str) 
                // First we escape the string using encodeURIComponent to get the UTF-8 encoding of the characters, 
                // then we convert the percent encodings into raw bytes, and finally feed it to btoa() function.
                utf8Bytes = encodeURIComponent(str).replace(/%([0-9A-F]2)/g, function(match, p1) 
                        return String.fromCharCode('0x' + p1);
                );

                return btoa(utf8Bytes);
            

            function handleInputFileChange(event) 
                //if we didnd't already have the "fileInput" var in scope, we could use "event.target" to get it
                if(fileInput.files.length>=1) 
                    //In this example, I'm putting the selected file's name in the title. You don't need to do this
                    document.title = fileInput.files[0].name;
                    downloadAnchor.setAttribute("download","edited_"+fileInput.files[0].name);
                
                else 
                    document.title = "FileReader Example";
                    downloadAnchor.setAttribute("download","edited_file.txt");
                
                var fr = new FileReader();
                fr.readAsText(fileInput.files[0]);
                fr.onload = function (event) 
                    //Both "event.target.result" and "fr.result" contain the file's contents (because "event.target" is === "fr")

                    textArea.value = event.target.result;
                    // OR
                    //textArea.value = fr.result;
                
            
            //The next is the fucntion returns a special kind of URL, a Data URL.
            //These kind of URLs don't point to a file, they ARE the data.
            //Read more here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
            function getDownloadableTextAreaContents() 
                return "data:text/plain,"+encodeURIComponent(textArea.value);
            
            function onDownloadClick(event) 
                //https://***.com/a/247261/6302540
                //var urlObject = "data:text/plain;base64,"+btoa(unescape(encodeURIComponent(textArea.value)));
                var urlObject = getDownloadableTextAreaContents();
                downloadAnchor.setAttribute("href",urlObject);
                downloadAnchor.click();
            

            fileInput.addEventListener("change",handleInputFileChange);
            saveFileButton.addEventListener("click",onDownloadClick);
        ,false);
    </script>
</head>
<body>
    <h1>File Reader Example:</h1>
    <input id="fileInput" type="file" accept=".txt"/>
    <textarea name="File Editor" id="fileEditor" placeholder="Your file's contents will show up here once you select the file!"></textarea>
    <button id="saveFileButton">Save File</button>
    <!--The next <a> tag is just a trick to make the browser download a file. It isn't displayed (style="display: none;")-->
    <a id="downloadAnchor" download="edited_file.txt" href="data:text/plain," style="display: none;"></a>
</body>
</html>

这是纯 JS 中的示例,但您可以轻松地对其进行调整以做出反应。一些改编是:

删除 ID,因为您在 React 中不需要它们; 您将拥有controlled textarea component,而不是简单的textarea。使用受控组件可以轻松设置和获取文本区域的值。 (如果你不了解 React 的 state 和 props 或受控组件的工作原理,你可以使用引用(这使得 React 代码几乎与普通 JS 相同)但我严重不推荐它,因为它是一种反模式并且只应在极少数情况下使用,例如一些非常、非常、、、、非常花哨的动画); changeclick 事件可以使用 onChangeonClick 属性轻松转换; 要做downloadAnchor.click(),可以关注this answer 隐藏锚点 (&lt;a&gt;) 的 hrefdownload 属性也可以是具有状态值的普通 prop,例如:

在反应中:

<a download=this.state.downloadFilename href=this.state.dataURL style="display: none;"/>

【讨论】:

你可以测试这个sn-p的代码。只需将其复制并粘贴到桌面上的文件中,例如 fileReader.html,然后使用浏览器打开即可。【参考方案3】:

您可以使用 https://github.com/kentcdodds/babel-plugin-preval 之类的东西在前端 react 应用程序中使用 fs 模块。

安装preval.macro

npm i preval.macro --save

然后将其添加到您的应用程序中

import preval from 'preval.macro';
const components = preval
    ` const fs = require('fs');
  const files = fs.readdirSync('src/atoms');
  module.exports = files;
`

组件将返回 src/atoms 下的文件夹。

【讨论】:

以上是关于react中读取本地文件的主要内容,如果未能解决你的问题,请参考以下文章

react 下载本地文件

react下载文件保存路径

如何启动react文件

react预览pdf文件(react-pdf)

React 使用Upload插件上传读取文件内容

请求本地文件夹中json文件的数据