无法使用 Multer 将文件从 React 上传到 Express
Can not upload file from React to Express with Multer
当我在邮递员中尝试 Post 请求时,我将文件发送到目的地没有任何问题,因此后端似乎没有问题。但是在前端出现了问题,我无法弄清楚问题是什么,当我尝试使用反应时弹出 MulterError: Unexpected field
错误。请有人告诉我我哪里出错了。
反应代码
import React, { Fragment, useState } from 'react';
import Message from './Message';
import Progress from './Progress';
import axios from 'axios';
const FileUpload = () => {
const [file, setFile] = useState('');
const [filename, setFilename] = useState('Choose File');
const [uploadedFile, setUploadedFile] = useState({});
const [message, setMessage] = useState('');
const [uploadPercentage, setUploadPercentage] = useState(0);
const onChange = e => {
setFile(e.target.files[0]);
setFilename(e.target.files[0].name);
};
const onSubmit = async e => {
e.preventDefault();
const formData = new FormData();
formData.append('file', file);
try {
const res = await axios.post('/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
},
onUploadProgress: progressEvent => {
setUploadPercentage(
parseInt(
Math.round((progressEvent.loaded * 100) / progressEvent.total)
)
);
// Clear percentage
setTimeout(() => setUploadPercentage(0), 10000);
}
});
const { fileName, filePath } = res.data;
setUploadedFile({ fileName, filePath });
setMessage('File Uploaded');
} catch (err) {
if (err.response.status === 500) {
setMessage('There was a problem with the server');
} else {
setMessage(err.response.data.msg);
}
}
};
return (
<Fragment>
{message ? <Message msg={message} /> : null}
<form onSubmit={onSubmit}>
<div className='custom-file mb-4'>
<input
type='file'
className='custom-file-input'
name="image"
id='customFile'
onChange={onChange}
/>
<label className='custom-file-label' htmlFor='customFile'>
{filename}
</label>
</div>
<Progress percentage={uploadPercentage} />
<input
type='submit'
value='Upload'
className='btn btn-primary btn-block mt-4'
/>
</form>
{uploadedFile ? (
<div className='row mt-5'>
<div className='col-md-6 m-auto'>
<h3 className='text-center'>{uploadedFile.fileName}</h3>
<img style={{ width: '100%' }} src={uploadedFile.filePath} alt='' />
</div>
</div>
) : null}
</Fragment>
);
};
export default FileUpload;
快递编码
const express = require('express');
const multer = require('multer')
const bodyParser = require('body-parser')
const path = require('path');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }))
const storage = multer.diskStorage({
destination: function(req, res, cb){
cb(null, `${__dirname}/client/public/uploads/`)
},
filename: function(req, files, cb){
cb(null, files.fieldname + '-' + Date.now()+ path.extname(files.originalname))
}
})
const upload = multer ({storage, limits: {fieldSize: 10000000}, fileFilter: function(req, file, cb){checkFileType(file, cb)}}).single('image')
function checkFileType(file, cb){
const filetypes = /jpeg|jpg|png|gif/;
const extname = filetypes.test(path.extname(file.originalname).toLocaleLowerCase())
const mimetype =filetypes.test(file.mimetype);
if(mimetype && extname){
return cb(null, true)
} else {
cb('Error: image only')
}
}
app.post('/upload', upload, (req, res) => {
console.log(req.file)
});
app.listen(5000, () => console.log('Server Started...'));
通过使用 .single('image')
,您希望在表单字段 'image'
中传递文件
但您使用的是 formData.append('file', file)
,它将文件附加到字段 'file'
您必须将字段名称更改为一致,'image'
或 'file'
当我在邮递员中尝试 Post 请求时,我将文件发送到目的地没有任何问题,因此后端似乎没有问题。但是在前端出现了问题,我无法弄清楚问题是什么,当我尝试使用反应时弹出 MulterError: Unexpected field
错误。请有人告诉我我哪里出错了。
反应代码
import React, { Fragment, useState } from 'react';
import Message from './Message';
import Progress from './Progress';
import axios from 'axios';
const FileUpload = () => {
const [file, setFile] = useState('');
const [filename, setFilename] = useState('Choose File');
const [uploadedFile, setUploadedFile] = useState({});
const [message, setMessage] = useState('');
const [uploadPercentage, setUploadPercentage] = useState(0);
const onChange = e => {
setFile(e.target.files[0]);
setFilename(e.target.files[0].name);
};
const onSubmit = async e => {
e.preventDefault();
const formData = new FormData();
formData.append('file', file);
try {
const res = await axios.post('/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
},
onUploadProgress: progressEvent => {
setUploadPercentage(
parseInt(
Math.round((progressEvent.loaded * 100) / progressEvent.total)
)
);
// Clear percentage
setTimeout(() => setUploadPercentage(0), 10000);
}
});
const { fileName, filePath } = res.data;
setUploadedFile({ fileName, filePath });
setMessage('File Uploaded');
} catch (err) {
if (err.response.status === 500) {
setMessage('There was a problem with the server');
} else {
setMessage(err.response.data.msg);
}
}
};
return (
<Fragment>
{message ? <Message msg={message} /> : null}
<form onSubmit={onSubmit}>
<div className='custom-file mb-4'>
<input
type='file'
className='custom-file-input'
name="image"
id='customFile'
onChange={onChange}
/>
<label className='custom-file-label' htmlFor='customFile'>
{filename}
</label>
</div>
<Progress percentage={uploadPercentage} />
<input
type='submit'
value='Upload'
className='btn btn-primary btn-block mt-4'
/>
</form>
{uploadedFile ? (
<div className='row mt-5'>
<div className='col-md-6 m-auto'>
<h3 className='text-center'>{uploadedFile.fileName}</h3>
<img style={{ width: '100%' }} src={uploadedFile.filePath} alt='' />
</div>
</div>
) : null}
</Fragment>
);
};
export default FileUpload;
快递编码
const express = require('express');
const multer = require('multer')
const bodyParser = require('body-parser')
const path = require('path');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }))
const storage = multer.diskStorage({
destination: function(req, res, cb){
cb(null, `${__dirname}/client/public/uploads/`)
},
filename: function(req, files, cb){
cb(null, files.fieldname + '-' + Date.now()+ path.extname(files.originalname))
}
})
const upload = multer ({storage, limits: {fieldSize: 10000000}, fileFilter: function(req, file, cb){checkFileType(file, cb)}}).single('image')
function checkFileType(file, cb){
const filetypes = /jpeg|jpg|png|gif/;
const extname = filetypes.test(path.extname(file.originalname).toLocaleLowerCase())
const mimetype =filetypes.test(file.mimetype);
if(mimetype && extname){
return cb(null, true)
} else {
cb('Error: image only')
}
}
app.post('/upload', upload, (req, res) => {
console.log(req.file)
});
app.listen(5000, () => console.log('Server Started...'));
通过使用 .single('image')
,您希望在表单字段 'image'
但您使用的是 formData.append('file', file)
,它将文件附加到字段 'file'
您必须将字段名称更改为一致,'image'
或 'file'