ReactJS Проблемы с формой загрузки изображений с пробелом в имени - PullRequest
0 голосов
/ 18 марта 2020

поэтому у меня есть это 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);

Это код, который я иметь на сервере. 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, '-')}`
      });
    }
  );
});

Ответы [ 3 ]

1 голос
/ 19 марта 2020

Похоже, вам нужно удалять пробелы только при настройке данных avatar и, возможно, свойства photo в formData?

Чтобы внести эти изменения, вы можете сделать это в слушатель загрузки файлов inChange:

const inChange = e => {
    const file = e.target.files[0];
    // replace spaces in filename with whatever character you want
    const fileNameNoSpaces = file.name.replace(/ /g, '_');

    setFile(file);
    setAvatar(fileNameNoSpaces);
    setFormData({
        ...formData,
        photo: fileNameNoSpaces
    });
};
1 голос
/ 19 марта 2020

Перед публикацией данных вы можете удалить все пробелы с пути и заменить их дефисами, например:

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

0 голосов
/ 29 марта 2020

Ответ этих двух парней был ключевым для решения проблемы, они освещают путь. Чтобы в конечном файле были тире вместо пробела, я добавляю это и в мой nodejs файл, и теперь он работает просто отлично file.mv( $ {__ dirname} / client / public / uploads / $ {file.name.replace ( / / г, '-')}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...