【发布时间】:2021-05-13 10:00:46
【问题描述】:
您好,希望有人可以提供帮助。使用MERN构建项目,需要有文件上传功能。已尝试实施各种解决方案,但似乎无济于事。任何帮助将不胜感激。
这是我的特快路线
const express = require('express');
const router = express.Router();
const auth = require('../../middleware/auth');
const { check, validationResult } = require('express-validator');
// bring in normalize to give us a proper url, regardless of what user entered
const normalize = require('normalize-url');
const checkObjectId = require('../../middleware/checkObjectId');
const path = require('path');
const multer = require('multer');
const Profile = require('../../models/Profile');
const User = require('../../models/User');
const Post = require('../../models/Post');
const upload = multer({
storage: multer.diskStorage({
destination(req, res, cb) {
cb(null, './files');
},
filename(req, file, cb) {
cb(null, `${new Date().getTime()}_${file.originalname}`);
}
}),
limits: {
fileSize: 1000000 // max file size 1MB = 1000000 bytes
},
fileFilter(req, file, cb) {
if (!file.originalname.match(/\.(jpeg|jpg|png)$/)) {
return cb(
new Error(
'only upload files with jpg, jpeg, format.'
)
);
}
cb(undefined, true); // continue with upload
}
});
// @route POST api/profile/upload
// @desc Upload profile image
// @access Private
router.post(
'/upload',
upload.single('file'),
async (req, res) => {
try {
console.log('Hello')
const { path, mimetype, originalname } = req.file;
const profileFields = {};
profileFields.user = req.user.id;
if (path) profileFields.image.path = path;
if (mimetype) profileFields.image.mimetype = mimetype;
if (originalname) profileFields.image.originalname = originalname;
let profile = await Profile.findOneAndUpdate(
{ user: req.user.id },
{ $set: profileFields },
{ new: true, upsert: true, setDefaultsOnInsert: true }
);
return res.json(profile);
} catch (err) {
console.log('help')
res.sendStatus(400).send('Error while uploading file. Please try again later.')
}
},
(error, req, res, next) => {
if (error) {
res.status(500).send(error.message);
}
}
);
这是我的模型
const mongoose = require('mongoose');
const ProfileSchema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'user'
},
location: {
type: String,
required: true
},
bio: {
type: String
},
image: {
origianlname: {
type: String,
required: true
},
path: {
type: String,
required: true
},
mineType: {
type: String,
required: true
},
},
topics: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'topic',
}
],
social: {
youtube: {
type: String
},
twitter: {
type: String
},
facebook: {
type: String
},
linkedin: {
type: String
},
instagram: {
type: String
}
},
date: {
type: Date,
default: Date.now
}
});
module.exports = mongoose.model('profile', ProfileSchema);
我在后端设置了一个名为 files 的文件夹
前端
动作文件
//Upload profile picture
export const uploadImage = (file) => async (dispatch) => {
try {
const formData = new FormData();
formData.append('file', file);
await axios.post('api/profile/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
});
dispatch(setAlert('Profile picture uploaded successfully', 'success'))
} catch (err) {
dispatch({
type: PROFILE_ERROR,
payload: { msg: err.response.statusText, status: err.response.status}
});
}
}
上传.js 组件文件
import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux';
import { Form, Button } from 'react-bootstrap';
import { uploadImage } from '../../actions/profile';
const Upload = ({ errors, dispatch }) => {
const [file, setFile] = useState(null);
const [isSubmitted, setIsSubmitted] = useState(false);
const [errorMsg, setErrorMsg] = useState(null);
useEffect(() => {
setErrorMsg(errors);
}, [errors]);
useEffect(() => {
setErrorMsg('');
}, [])
const handleOnChange = (event) => {
const file = event.target.files[0];
setFile(file);
};
const handleFormSubmit = (event) => {
event.preventDefault();
if (file) {
setErrorMsg('');
dispatch(uploadImage(file));
setIsSubmitted(true);
}
};
return (
<React.Fragment>
{errorMsg && errorMsg.upload_error ? (
<p className="errorMsg centered-message">{errorMsg.upload_error}</p>
) : (
isSubmitted && (
<p className="successMsg centered-message">
Photo uploaded successfully
</p>
)
)}
<Form
onSubmit={handleFormSubmit}
method="post"
encType="multipart/form-data"
className="upload-form"
>
<Form.Group>
<Form.Label>Choose photo to upload</Form.Label>
<Form.Control type ="file" name="file" onChange={handleOnChange} />
</Form.Group>
<Button
variant="primary"
type="submit"
className={`${!file ? 'disabled submit-btn' : 'submit-btn'}`}
>
Upload
</Button>
</Form>
</React.Fragment>
);
};
const mapStateToProps = (state) => ({
file: state.file || [],
errors: state.errors || {}
});
export default connect(mapStateToProps)(Upload);
减速器文件
import {
GET_PROFILE,
PROFILE_ERROR,
CLEAR_PROFILE,
GET_PROFILES,
} from '../actions/types';
const initialState = {
profile: null,
profiles: [],
repos: [],
loading: true,
error: {}
};
function profileReducer(state = initialState, action) {
const { type, payload } = action;
switch (type) {
case GET_PROFILE:
return {
...state,
profile: payload,
loading: false
};
case GET_PROFILES:
return {
...state,
profiles: payload,
loading: false
};
case PROFILE_ERROR:
return {
...state,
error: payload,
loading: false,
profile: null
};
case CLEAR_PROFILE:
return {
...state,
profile: null,
repos: []
};
default:
return state;
}
}
export default profileReducer;
希望有人能看到我哪里出错了。我在 redux devtools 上的操作负载说 PROFILE_ERROR 正在运行,我收到状态 400 错误请求。
【问题讨论】:
-
您的模型中有一个错字 originalname 拼写错误,这肯定会引发错误
-
谢谢你已经修复它,但还没有解决问题
标签: javascript reactjs express mongoose react-redux