我正在尝试创建上传个人资料图片方法,帮助用户在网站上上传他们的个人资料图片,但我不知道如何将图像从客户端发送到服务器并将这些图像存储在 cloudinary 或 firebase 上。< /p>
我的路线如下所示: ProfileAPI.js
const express = require("express");
const router = express.Router();
const { body, param } = require("express-validator");
const { catchErrors } = require("../errors/errorHandlers");
const multer = require('multer');
const uuidv4 = require('uuid/v4');
const upload_dir = './images';
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, upload_dir);
},
filename: (req, file, cb) => {
cb(null, `${uuidv4()}-${file.filename.toLowerCase}`);
}
});
const upload = multer({
storage: storage,
fileFilter: (req, file, cb) => {
if (
file.mimetype == 'image/png' ||
file.mimetype == 'image/jpg' ||
file.mimetype == 'image/jpeg'
) {
cb(null, true);
} else {
cb(null, false);
return cb(new Error('Only .png, .jpg and .jpeg format allowed!'));
}
}
});
const {
getUserProfile,
getUsersPublicProfile,
lookUpId,
updateUserProfile,
updateUserEmail,
deleteUserProfile,
// deleteUserSkill,
addPlayersProfile,
getCreatedPlayers,
updatePlayersProfile,
deleteUserCreatedPlayer,
} = require("./profilesController");
router.post(
"/upload",
upload.single('profileImg'),
updateUserProfile
);
所以关键点是设置存储告诉哪里上传+上传文件过滤器,对吗?
还有将 `upload.single('profileImg') 的 route.post,对吗?该路由将包括我的 updateUserProfile 控制器,可在此处找到: profilesController.js
exports.updateUserProfile = async (req, res) => {
const userId = req.session.passport.user.id;
// This array will contain all the update functions to run.
const updates = [];
// If a gravatar url has not been generated, do it now.
const pictureValue = gravatar.url(
req.body.email,
{ s: "100", r: "pg", d: "retro" },
true
);
const payload = {
fullname: req.body.fullname,
location: req.body.location,
webpage: req.body.webpage,
linkedin: req.body.linkedin,
institution: req.body.institution,
bio: req.body.bio,
major: req.body.major,
mergedTo: userId,
picture: pictureValue,
skillone: req.body.skillone,
skilltwo: req.body.skilltwo,
skillthree: req.body.skillthree
};
}
现在是前端代码(react.js):
这是我在 React 应用程序中加载的表单:
UserProfile.js
const UserProfile = (serverUserData) => {
const appState = useContext(GlobalContext);
const { currentUser } = appState;
const { email, picture, name } = currentUser;
const [isVerified, setIsVerified] = useState(false);
const checkVerificationData = () => {
axios.get("/api/v1/profiles/profile").then((res) => {
const { data } = res;
if (data.verifiedDT) {
setIsVerified(data.verifiedDT);
}
});
};
useEffect(() => {
checkVerificationData();
}, [isVerified]);
// Upload user avatar function
const [imageSelected, setImageSelected] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
const formData = new FormData();
formData.append('email', email);
formData.append('name', name);
formData.append('profileImg', imageSelected);
axios
.post(`/upload`, formData)
.then(() => console.log("success"))
.catch(err => console.log(err));
};
const onFileChange = (e) => {
setImageSelected({ profileImg: e.target.files[0] });
};
};
const classes = useStyles();
return (
<div className={classes.root}>
<Grid item xs={12}
container
direction="row"
justify="center"
alignItems="center"
spacing={4}>
<Grid item>
<Grid item>
<UserCard
picture={currentUser.picture}
userEmail={email}
name={name}
isVerified={isVerified}
handleSubmit={handleSubmit}
onFileChange={onFileChange}
/>
<br />
</Grid>
这里是用户可以上传他们的个人资料照片的地方: UserCard.js
{picture ? (
<div>
<Avatar
src={picture}
alt="Avatar"
className="avatar--profile_image"
/>
<input
type="file"
onChange={onFileChange}
/>
<button onClick={handleSubmit}>Submit</button>
</div>
) : (
<AccountCircleIcon className="avatar--profile_image" />
)}
因此,当输入内容并点击添加按钮时,我的 api 声明 req.file 未定义,我无法找出原因。
谁能帮我分析错误?
答案 0 :(得分:1)
要上传文件,您需要使用 contentType: "multipart/form-data"。 参考以下实现文件上传。
helper 函数来创建一个带有所需标头的实例。您可以在此处添加任何其他人。
const getInstance = () => {
return axios.create({
headers: {
"Content-Type": "multipart/form-data",
},
});
}
使用要上传的文件调用此方法
const fileUplaod = (file) => {
let formData = new FormData();
formData.append("images", file, file.name);
getInstance()
.post(endpoint_post_url, formData)
.then((response) => {
console.log("IMAGES_SUBMIT_SUCCESS");
})
.catch((err) => {
console.error("image submit error", err);
});
}
检查后端代码中的请求正文。您也可以将多张图片上传到同一媒体资源。它将是请求对象中的一个数组。
答案 1 :(得分:0)
编辑 handleSubmit 函数以向 axios 调用添加配置。
const handleSubmit = (e) => {
e.preventDefault();
const formData = new FormData();
formData.append('email', email);
formData.append('name', name);
formData.append('profileImg', imageSelected);
axios
.post(`/upload`, formData, {
headers: {
'Content-Type': "multipart/form-data"
}
})
.then(() => console.log("success"))
.catch(err => console.log(err));
};