MERN Stack 应用程序 - 用户头像上传 - 渲染部署后出现 500 错误

问题描述 投票:0回答:1

我有一个 MERN 堆栈应用程序,我将其部署到 Render(服务器端作为 Web 服务,前端作为静态)。
在我的应用程序中,我有一个配置文件,用户可以在其中上传头像图像。我将图像作为 URL 字符串存储在用户模型的 MongoDB Atlas_ 中。

图像保存在服务器上的上传文件夹中。图像上传工作正常,并且从部署和本地环境中成功获取图像。但过了一会儿,我在获取相同图像时开始出现内部服务器错误。

这个问题是什么原因以及如何解决?或者有没有更好的方法在 MongoDB Atlas 中存储图像而不使用云或GridFS

这是我设置用户头像的方法:

const setUserAvatar = async (req, res) => {
    try {
        if (!req.user || !req.user.id) {
            return res.status(401).json({ message: 'Unauthorized' });
        }
        const user = await User.findById(req.user.id);
        if (!user) {
            return res.status(404).json({ message: 'User not found' });
        }

        if (!req.file) {
            return res.status(400).json({ message: 'No file uploaded' });
        }

        const fileName = `avatar_${user.id}_${Date.now()}.png`;
        const filePath = path.join(__dirname, '..', 'uploads', fileName);

        fs.writeFileSync(filePath, req.file.buffer);

        user.avatar = { data: fileName };
        await user.save();


        res.status(200).json({ message: 'Avatar uploaded successfully' });

    } catch (error) {
        console.error('Error uploading avatar', error);
        res.status(500).json({ message: 'Internal Server Error' });

    }
};

并得到:

const getUserAvatar = async (req, res) => {
    const userId = req.user.id;
    try {
        const user = await User.findById(userId);
        if (user.avatar.data === null) {
            return res.status(404).json({ message: 'No avatar found' })
        }
        if (!user || !user.avatar.data) {
            res.send(user.avatar.data)
        } else {
            const filePath = path.join(__dirname, '..', 'uploads', user.avatar.data);
            const avatarData = fs.readFileSync(filePath);
            res.setHeader('Content-Type', 'image/*');
            res.send(avatarData);
        }

    } catch (error) {
        console.error('Error fetching avatar', error);
        res.status(500).json({ message: 'Internal Server Error' });
    }
};

前端如何处理头像变更:


   const handleAvatarChange = async (e) => {
        const token = localStorage.getItem('token');
        if (token) {
            try {
                const formData = new FormData();
                formData.append('avatar', e.target.files[0])
                const response = await fetch('RENDERLINK/avatar', {
                    'method': 'POST',
                    'headers': {
                        'Authorization': `Bearer ${token}`,
                    },
                    'body': formData,
                    'credentials': 'include'
                })
                if (response.status === 200) {
                    getUser()
                    toast.success('Avatar changed successfully')
                } else if (response.status === 400) {
                    toast.error('No file selected')
                } else {
                    toast.error('Error changing avatar')
                }
            } catch (error) {
                toast.error('Oops! Something went wrong. Please try again later.')
            }
        } else {
            console.log('No token found')
            navigate('/login')
        }
    }

获取包括头像在内的用户数据:

    const getUser = async () => {
        const token = localStorage.getItem('token');
        if (token) {
            try {
                const response = await fetch('RENDERLINK/profile', {
                    'method': 'POST',
                    'headers': {
                        'Content-Type': 'application/json',
                        'Authorization': `Bearer ${token}`,
                    },
                    'credentials': 'include'
                })

                if (response.ok) {
                    const data = await response.json();

                    setUser({ username: data.username, email: data.email, avatar: data.avatar.data })
                    if (data.avatar.data !== null) {
                        // Fetch and set the avatar image
                        const avatarResponse = await fetch('RENDERLINK/get_avatar', {
                            headers: {
                                'Authorization': `Bearer ${token}`,
                            },
                            credentials: 'include',
                        });
                        const avatarBlob = await avatarResponse.blob();
                        const avatarUrl = URL.createObjectURL(avatarBlob);
                        setUser((prevUser) => ({ ...prevUser, avatar: avatarUrl }));
                        setLoading(false)
                    }

                } else if (response.status === 500) {
                    toast.error('Oops! Something went wrong. Please try again later.')
                }

            } catch (error) {
                toast.error('Oops! Something went wrong. Please try again later.')
            }
        } else {
            console.log('No token found')
            navigate('/login')
        }
    }
reactjs mongodb file-upload mern render.com
1个回答
0
投票

在渲染中,您可以创建磁盘并将文件保存在项目文件夹之外。它解决了我的问题,因为现在当我需要将更新的代码推送到 GitHub 时,它不会影响用户上传的图像。

© www.soinside.com 2019 - 2024. All rights reserved.