ReactJS Image Upload表单文件名中存在空格问题



所以我有了这个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, '-')}`
});
}
);
});

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

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

formData中设置avatar数据和photo属性时,似乎只需要删除空格?

要进行这些更改,您可以在文件上载侦听器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
});
};

这两个人的反应是解决问题的关键,他们照亮了道路。为了确保最终的文件将有破折号而不是空格,我也将其添加到我的nodejs文件中,现在它运行得很好file.mv( ${__dirname}/client/public/uploads/${file.name.replace(//g,'-'(}

最新更新