javascript 在react中上传和读取文件

bsxbgnwa  于 2023-05-05  发布在  Java
关注(0)|答案(6)|浏览(531)

我试图用React上传一个文件并查看它的内容,但它给我的是C:\fakepath\。我知道为什么它给出fakepath,但是在react中上传和读取文件内容的正确方法是什么?

<input type="file"
      name="myFile"
      onChange={this.handleChange} />

handleChange: function(e) {
        switch (e.target.name) {
        case 'myFile':
            const data = new FormData();
            data.append('file', e.target.value);
            console.log(data);
        default:
            console.error('Error in handleChange()'); break;
        }
    },
gmxoilav

gmxoilav1#

要获取文件信息,您需要使用event.target.files,它是选定文件的数组。这些都可以通过FormData对象轻松上传。请参见下面的代码段:

class FileInput extends React.Component {
    constructor(props) {
      super(props)
      this.uploadFile = this.uploadFile.bind(this);
    }
    
    uploadFile(event) {
        let file = event.target.files[0];
        console.log(file);
        
        if (file) {
          let data = new FormData();
          data.append('file', file);
          // axios.post('/files', data)...
        }
    }
    
    render() {
      return <span>
        <input type="file"
        name="myFile"
        onChange={this.uploadFile} />
      </span>
    }
}

ReactDOM.render(<FileInput />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js"></script>
<div id="root"></div>

您可能希望查看FileReader,如果您希望在客户端处理文件,例如显示图像,它可以提供帮助。
https://developer.mozilla.org/en-US/docs/Web/API/FileReader

q7solyqu

q7solyqu2#

您可以使用React Dropzone Uploader,它可以为您提供开箱即用的文件预览(包括图像缩略图),还可以为您处理上传。
onChangeStatus prop中,您可以对文件的meta数据和file本身做出React,这意味着您可以在上传文件之前或之后进行任何类型的客户端处理。

import 'react-dropzone-uploader/dist/styles.css'
import Dropzone from 'react-dropzone-uploader'

const Uploader = () => {  
  return (
    <Dropzone
      getUploadParams={() => ({ url: 'https://httpbin.org/post' })} // specify upload params and url for your files
      onChangeStatus={({ meta, file }, status) => { console.log(status, meta, file) }}
      onSubmit={(files) => { console.log(files.map(f => f.meta)) }}
      accept="image/*,audio/*,video/*"
    />
  )
}

上传有进度指示器,可以取消或重新启动。用户界面是完全可定制的。
全面披露:我写了这个图书馆。

qf9go6mv

qf9go6mv3#

尝试在后端使用Multer和gridfs-storage,并将fileID与mongoose模式沿着存储。

// Create a storage object with a given configuration
const storage = require('multer-gridfs-storage')({
  url: 'MONGOP DB ATLAS URL'
});

// Set multer storage engine to the newly created object
const upload = multer({ storage }).single('file');

router.post('/', upload, (req, res) => {

  const newreminder = new Reminders({
    category: req.body.category,
    name:req.body.name,
    type: req.body.type,
    exdate: req.body.exdate,
    location:req.body.location,
    notes:req.body.notes,
    fileID: req.file.id
  });
  newreminder.save(function(err){
    if(err){
      console.log(err);
      return;
    }

    res.json({ "success": "true"});
  });

});

然后在前端正常处理它(使用Axios)并上传整个文件,并以正常的React方式抓住所有信息:

onSubmit = (e) => {
  e.preventDefault;
  const formData = new FormData();
  formData.append({ [e.target.name]: e.target.value })
  formData.append('file', e.target.files[0]);

  axios.post({
    method:'POST',
    url:'EXPRESS JS POST REQUEST PATH',
    data: formData,
    config:{ headers: {'Content-Type':'multipart/form-data, boundary=${form._boundary}'}}
  })
  .then(res => console.log(res))
  .catch(err => console.log('Error', err))
}
aor9mmx1

aor9mmx14#

你用过dropzone吗?看到这个react-dropzone
容易实现,上传和返回URL,如果这很重要。

onDrop: acceptedFiles => {
    const req = request.post('/upload');
    acceptedFiles.forEach(file => {
        req.attach(file.name, file);
    });
    req.end(callback);
}
kxkpmulp

kxkpmulp5#

您可以使用FileReader onload方法读取文件数据,然后将其发送到服务器。
你可以发现这对使用React ReactJS File Reader中的File Reader处理文件很有用

jvidinwx

jvidinwx6#

为了补充这里的其他答案,特别是对于React的新手来说,理解react句柄的形式与人们习惯的形式略有不同是很有用的。
在高级别上,react建议使用“受控组件”:
在大多数情况下,我们建议使用受控组件来实现窗体。在受控组件中,表单数据由React组件处理。另一种方法是不受控制的组件,其中表单数据由DOM本身处理。
这实质上意味着用户输入,例如,文本字段也是组件的状态,并且当用户更新它时,状态被更新,并且状态的值被显示在表单中。这意味着状态和表单数据总是同步的。
对于输入类型的文件,这将不起作用,因为文件输入值是只读的。因此,不能使用受控部件,而是使用“不受控部件”。
在React中,an始终是一个不受控制的组件,因为它的值只能由用户设置,而不能通过编程方式设置。
推荐的输入文件类型的方法(在撰写本文时)如下,来自react文档www.example.comhttps://reactjs.org/docs/uncontrolled-components.html#the-file-input-tag:

class FileInput extends React.Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.fileInput = React.createRef();
  }
  handleSubmit(event) {
    event.preventDefault();
    alert(
      `Selected file - ${this.fileInput.current.files[0].name}`
    );
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Upload file:
          <input type="file" ref={this.fileInput} />
        </label>
        <br />
        <button type="submit">Submit</button>
      </form>
    );
  }
}

ReactDOM.render(
  <FileInput />,
  document.getElementById('root')
);

该文档包括一个codepen示例,可以在其上构建。

相关问题