Web编程新手求助:如何实现基于MongoDB的用户个人资料页
Hey there! Let's get your user profile page sorted out—you're already off to a good start with your Handlebars template, so we'll fix that up first, then tackle how to connect everything to MongoDB (important note: frontend HTML can't directly access MongoDB—we need a backend layer to handle that!).
Your current code has a broken mailto link, plus it's smart to add a fallback image in case the user hasn't uploaded an avatar yet. Here's the cleaned-up version:
<div class="row"> <div class="col-md-4"> <h1><%= user.firstName %> <%= user.lastName %></h1> <div class="thumbnail"> <!-- Fallback to a default avatar if user hasn't set one --> <img src="<%= user.avatar || '/images/default-avatar.png' %>" alt="User profile image" class="img-fluid"> </div> <!-- Fixed mailto link --> <p><a href="mailto:<%= user.email %>"><%= user.email %></a></p> </div> </div>
Frontend code (HTML/Handlebars) can't talk directly to MongoDB—you need a backend (I’ll assume you’re using Node.js/Express since you’re working with Handlebars) to fetch user data and pass it to your template. Here's the step-by-step setup:
Step 1: Set Up Mongoose (MongoDB ODM)
First, install Mongoose to simplify interactions with MongoDB:
npm install mongoose
Create a user schema and model (make a file like models/User.js):
const mongoose = require('mongoose'); const userSchema = new mongoose.Schema({ firstName: { type: String, required: true }, lastName: { type: String, required: true }, email: { type: String, required: true, unique: true }, avatar: { type: String, default: '' } // Stores the path/URL to the avatar image }); module.exports = mongoose.model('User', userSchema);
Step 2: Connect MongoDB to Your Express App
In your main server file (e.g., app.js):
const mongoose = require('mongoose'); // Connect to your MongoDB instance (replace with your database URI) mongoose.connect('mongodb://localhost:27017/your-database-name') .then(() => console.log('Connected to MongoDB successfully')) .catch(err => console.error('MongoDB connection error:', err));
Step 3: Create a Route to Render the Profile Page
You need a route that fetches the logged-in user's data from MongoDB and passes it to your Handlebars template. Assuming you're using a session-based auth system (like express-session):
const express = require('express'); const router = express.Router(); const User = require('../models/User'); // Profile page route router.get('/profile', async (req, res) => { try { // Fetch the logged-in user (req.user should be set by your auth middleware) const user = await User.findById(req.user._id); if (!user) { return res.redirect('/login'); } // Pass user data to the Handlebars template res.render('profile', { user }); } catch (err) { console.error(err); res.status(500).send('Server error'); } }); module.exports = router;
Since users need to select their own avatar, you’ll need an upload system. Use multer to handle file uploads:
First install multer:
npm install multer
Set up multer in your server (create a config/multer.js file):
const multer = require('multer'); const path = require('path'); // Configure storage for uploaded avatars const storage = multer.diskStorage({ destination: (req, file, cb) => { cb(null, 'public/images/avatars'); // Ensure this folder exists! }, filename: (req, file, cb) => { // Create a unique filename to avoid overwrites cb(null, `${req.user._id}-${Date.now()}${path.extname(file.originalname)}`); } }); // Filter to only accept image files const fileFilter = (req, file, cb) => { const allowedTypes = ['image/jpeg', 'image/png', 'image/gif']; if (allowedTypes.includes(file.mimetype)) { cb(null, true); } else { cb(new Error('Only image files are allowed!'), false); } }; const upload = multer({ storage, fileFilter }); module.exports = upload;
Add a route to handle avatar uploads and update the user's avatar field:
const upload = require('../config/multer'); // Route to update avatar router.post('/profile/avatar', upload.single('avatar'), async (req, res) => { try { // Update the user's avatar path (relative to the public folder) await User.findByIdAndUpdate( req.user._id, { avatar: `/images/avatars/${req.file.filename}` }, { new: true } ); res.redirect('/profile'); } catch (err) { console.error(err); res.status(500).send('Error uploading avatar'); } });
Add an upload form to your profile template so users can select an avatar:
<div class="row mt-4"> <div class="col-md-4"> <h3>Update Your Avatar</h3> <form action="/profile/avatar" method="POST" enctype="multipart/form-data"> <div class="form-group"> <input type="file" name="avatar" accept="image/*" class="form-control-file"> </div> <button type="submit" class="btn btn-primary">Upload Avatar</button> </form> </div> </div>
- Never expose MongoDB credentials or connect directly from the frontend: All database interactions must go through your backend server to keep your data secure.
- Make sure the
public/images/avatarsfolder exists (create it manually or add code to generate it on server startup). - If you're not using session-based auth, adjust the route to fetch the user by whatever identifier you're using (like an email from a JWT token).
内容的提问来源于stack exchange,提问作者StackOverLow

