首页 > 解决方案 > ReactJS图像上传表单文件名中的空格问题

问题描述

所以我有这个 ReactJS 应用程序,我创建了一个注册表单,人们可以在其中添加他们自己的图片,并且正在工作,但我正在提前考虑,我想在发生之前解决这个问题。

会有人会在名称中添加带有空格的文件,但我不知道如何使它工作。

这是我的代码

import React, { Fragment, useState } from 'react';
import { connect } from 'react-redux';
import { Link, Redirect } from 'react-router-dom';
import { Button } from 'react-bootstrap';
import axios from 'axios';
import { setAlert } from '../../actions/alert';
import { register } from '../../actions/auth';
import PropTypes from 'prop-types';

// Components
import Message from '../layout/Message';
import Progress from '../layout/Progress';

const Register = ({ setAlert, register, isAuthenticated }) => {
  const [file, setFile] = useState('');
  const [avatar, setAvatar] = useState('Your File');
  const [uploadedFile, setUploadedFile] = useState({});
  const [message, setMessage] = useState('');
  const [uploadPer, setUploadPer] = useState(0);
  const [formData, setFormData] = useState({
    usertype: 'client',
    name: '',
    lastname: '',
    companyname: '',
    title: '',
    phonenumber: '',
    email: '',
    password: '',
    password2: '',
    photo: 'placeholder.png'
  });

  const {
    usertype,
    name,
    lastname,
    companyname,
    title,
    phonenumber,
    email,
    password,
    password2,
    photo
  } = formData;

  const onChange = e => {
    setFormData({
      ...formData,
      [e.target.name]: e.target.value
    });
  };

  const inChange = e => {
    setFile(e.target.files[0]);
    setAvatar(e.target.files[0].name.replace(/ /g, '-'));
    setFormData({
      ...formData,
      photo: e.target.files[0].name.replace(/ /g, '-')
    });
  };

  const onPress = async e => {
    const formData = new FormData();
    formData.append('avatar', file);

    try {
      const res = await axios.post('/avatars', formData, {
        headers: {
          'Content-Type': 'multipart/form-data'
        },
        onUploadProgress: progressEvent => {
          setUploadPer(
            parseInt(
              Math.round((progressEvent.loaded * 100) / progressEvent.total)
            )
          );
          // Clear percentage
          setTimeout(() => setUploadPer(0), 20000);
        }
      });

      const { avatar, filePath } = res.data;

      setUploadedFile({ avatar, filePath });
      setMessage('File Uploaded');
    } catch (err) {
      if (err.response.status === 500) {
        setMessage('There was a problem witht the server');
      } else {
        setMessage(err.response.data.msg);
      }
    }
  };

  const onSubmit = e => {
    e.preventDefault();
    if (password !== password2) {
      setAlert('Passwords do not match', 'danger');
    } else {
      register({
        usertype,
        name,
        lastname,
        companyname,
        title,
        phonenumber,
        email,
        password,
        photo
      });
    }
  };

  // Redirect if registered in
  if (isAuthenticated) {
    return <Redirect to="/dashboard" />;
  }

  return (
    <Fragment>
      <section className="section-size-4 lighter-bg">
        <div className="container">
          <div className="grid">
            <div className="column-6">
              <h4>Are you new to us?</h4>
              <h1 className="animated-text">Register Now</h1>

              <div className="space-3"></div>
              <form
                className="box white shadow text-left"
                onSubmit={e => onSubmit(e)}
              >
                <label>Name *</label>
                <input
                  name="name"
                  type="text"
                  placeholder="John"
                  value={name}
                  onChange={e => onChange(e)}
                />
                <label>Last Name *</label>
                <input
                  name="lastname"
                  type="text"
                  placeholder="Doe"
                  value={lastname}
                  onChange={e => onChange(e)}
                />
                <label>Company Name</label>
                <input
                  name="companyname"
                  type="text"
                  placeholder="Company Inc"
                  value={companyname}
                  onChange={e => onChange(e)}
                />
                <label>Title or Position</label>
                <input
                  name="title"
                  type="text"
                  placeholder="e.g. CEO or Office Manager"
                  value={title}
                  onChange={e => onChange(e)}
                />
                <label>Phone *</label>
                <input
                  name="phonenumber"
                  type="text"
                  placeholder="(844) 631-2665"
                  value={phonenumber}
                  onChange={e => onChange(e)}
                />
                <label>Email *</label>
                <input
                  name="email"
                  type="email"
                  placeholder="johndoe@example.com"
                  value={email}
                  onChange={e => onChange(e)}
                />
                <label>Password *</label>
                <input
                  name="password"
                  type="password"
                  placeholder="Use 6 or more characters"
                  value={password}
                  onChange={e => onChange(e)}
                  minLength="6"
                />
                <label>Confirm Password *</label>
                <input
                  name="password2"
                  type="password"
                  placeholder="Type password again"
                  value={password2}
                  onChange={e => onChange(e)}
                  minLength="6"
                />
                <label>Profile photo</label>
                <div className="grid">
                  <div className="column-8">
                    <input
                      id="myph"
                      className="avatar-input"
                      type="text"
                      name="photo"
                      value={avatar}
                      onChange={e => onChange(e)}
                    />
                  </div>
                  <div className="column-4">
                    <input
                      type="file"
                      id="fileId"
                      name="file"
                      style={{ display: 'none' }}
                      onChange={inChange}
                    />
                    <label
                      className="upload-button"
                      htmlFor="fileId"
                      id="filelabel"
                      value={uploadedFile.filePath}
                    >
                      <i className="fas fa-upload"></i> <span>Browse</span>
                    </label>
                  </div>
                  <div className="column-12">
                    {message ? <Message msg={message} /> : null}
                    <Button onClick={onPress} variant="primary" size="sm">
                      Upload Image
                    </Button>

                    {uploadedFile ? (
                      <div className="grid placeholder">
                        <div className="column-12">
                          <div className="uploaded-image">
                            <img
                              src={uploadedFile.filePath}
                              alt={uploadedFile.avatar}
                            />
                          </div>
                        </div>
                      </div>
                    ) : null}
                  </div>
                  <div className="column-12">
                    <Progress percentage={uploadPer} />
                  </div>
                </div>
                <button className="button" type="submit">
                  Submit
                </button>
              </form>

              <div className="space-3"></div>
            </div>
            <div className="column-5 offset-1 text-right">
              <h5>Are you a member?</h5>
              <Link to="/login" className="register-sign-in about-cta-button">
                Log In Here
              </Link>
            </div>
          </div>
        </div>
      </section>
    </Fragment>
  );
};

Register.propTypes = {
  setAlert: PropTypes.func.isRequired,
  register: PropTypes.func.isRequired,
  isAuthenticated: PropTypes.bool
};

const mapStateToProps = state => ({
  isAuthenticated: state.auth.isAuthenticated
});

export default connect(mapStateToProps, { setAlert, register })(Register);

这是我在 server.js 中的代码,因此您可以了解文件是如何返回的。我不明白为什么现在在按上传后刷新,我可以在预览框中看到文件,但它会刷新并恢复为默认值。

// Avatar upload endpoint
app.post('/avatars', (req, res) => {
  if (req.files === null) {
    return res.status(400).json({ msg: 'No file was uploaded' });
  }

  const file = req.files.avatar;

  file.mv(
    `${__dirname}/client/public/uploads/${file.name.replace(/ /g, '-')}`,
    err => {
      if (err) {
        console.error(err);
        return res.status(500).send(err);
      }

      res.json({
        avatar: file.name.replace(/ /g, '-'),
        filePath: `/uploads/${file.name.replace(/ /g, '-')}`
      });
    }
  );
});

标签: javascriptreactjsreact-router

解决方案


在发布数据之前,您可以从路径中删除所有空格并用连字符替换它们,如下所示:

filePath.replace(/ /g,'-')


推荐阅读