javascript - 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, '-')}`
});
}
);
});
解决方案
在发布数据之前,您可以从路径中删除所有空格并用连字符替换它们,如下所示:
filePath.replace(/ /g,'-')
推荐阅读
- html - CSS 中的背景图像在移动设备上不正确
- html - 如何使 HTML href 功能将用户重定向到万维网网页而不是用户计算机内的文件夹?
- android - 无法构建 GStreamer 管道;Android中没有元素x265enc
- sql - 在 where 子句中使用多个条件时出现关系运算符错误
- javascript - 不在嵌入消息中发送图像
- html - 感觉不可能删除页脚下方的空白
- python-3.x - 我们如何调用 __iter__(self) 下的 self.n?它是实例属性吗?
- python - 在不使用大小/颜色的情况下将图例添加到线和条到 Altair 图表
- c++ - 用 1D Arrat 中的条目替换 2D 数组中的条目的最快方法
- javascript - 显示具有适当缩进的 pdf 文件