如何从MongoDB获取数据并在HTML页面展示?已有server.js配置
Hey, let's get your MongoDB data showing up on that /history page! The core issue right now is that your /history route is only sending the raw HTML file—you're fetching data with Idea.find() but never passing it to the frontend. Here are two practical solutions you can choose from, depending on whether you prefer server-side rendering or a decoupled frontend approach:
Option 1: Server-Side Rendering with EJS (Simpler for Small Projects)
This method uses a template engine to inject data directly into your HTML before sending it to the browser. We'll use EJS, which is easy to set up with Express.
Step 1: Install EJS
First, add the EJS package to your project:
npm install ejs --save
Step 2: Configure Express to Use EJS
Update your server.js to tell Express to use EJS as the template engine, and point it to your HTML directory:
const path = require('path'); const express = require('express'); // ... rest of your imports ... const app = express(); // Add these lines to set up EJS app.set('view engine', 'ejs'); // Point to your HTML directory (adjust the path if needed) app.set('views', path.join(__dirname, './js/newJs')); // ... rest of your server setup (mongoose connection, middleware, etc.) ...
Step 3: Convert Your HTML to an EJS Template
Rename history.html to history.ejs, then add code to render the data:
<!DOCTYPE html> <html> <head> <title>Salary History</title> </head> <body> <h1>Your Salary History</h1> <div class="history-container"> <% if (ideas.length === 0) { %> <p>No history entries yet!</p> <% } else { %> <ul> <% ideas.forEach(idea => { %> <li class="history-item"> <strong>Date:</strong> <%= idea.date %> | <strong>Amount:</strong> <%= idea.amount %> | <strong>Hours:</strong> <%= idea.hours %> | <strong>Salary:</strong> <%= idea.salary %> | <strong>Tip:</strong> <%= idea.tip %> </li> <% }) %> </ul> <% } %> </div> </body> </html>
Step 4: Update the /history Route to Pass Data
Modify your route to wait for the MongoDB query, then pass the results to the EJS template:
app.get('/history', async (req, res) => { try { // Wait for the database query to finish const ideas = await Idea.find({}).sort({ date: 'desc' }); // Render the EJS template and pass the data res.render('history', { ideas: ideas }); } catch (err) { console.error('Error fetching history data:', err); res.status(500).send('Failed to load history'); } });
Option 2: Frontend AJAX Request (Decoupled Approach)
If you want to keep your frontend separate from the backend, you can create an API endpoint to return JSON data, then use JavaScript in your HTML to fetch and display it.
Step 1: Add an API Route in server.js
Add this route to return your MongoDB data as JSON:
// API endpoint for fetching history data app.get('/api/history', async (req, res) => { try { const ideas = await Idea.find({}).sort({ date: 'desc' }); res.json(ideas); } catch (err) { console.error('Error fetching API data:', err); res.status(500).json({ error: 'Failed to fetch history data' }); } });
Step 2: Update history.html to Fetch and Render Data
Add JavaScript to your HTML to call the API and dynamically populate the page:
<!DOCTYPE html> <html> <head> <title>Salary History</title> </head> <body> <h1>Your Salary History</h1> <div class="history-container"> <ul id="historyList"></ul> <p id="errorMessage" style="color: red; display: none;"></p> </div> <script> // Fetch data when the page loads window.addEventListener('load', async () => { const historyList = document.getElementById('historyList'); const errorMessage = document.getElementById('errorMessage'); try { const response = await fetch('/api/history'); if (!response.ok) throw new Error('Failed to fetch data'); const ideas = await response.json(); if (ideas.length === 0) { historyList.innerHTML = '<li>No history entries yet!</li>'; return; } // Build list items from the data ideas.forEach(idea => { const li = document.createElement('li'); li.className = 'history-item'; li.textContent = `Date: ${idea.date} | Amount: ${idea.amount} | Hours: ${idea.hours} | Salary: ${idea.salary} | Tip: ${idea.tip}`; historyList.appendChild(li); }); } catch (err) { errorMessage.textContent = err.message; errorMessage.style.display = 'block'; } }); </script> </body> </html>
Quick Note on Mongoose Setup
Just a heads-up: The useMongoClient option you're using in mongoose.connect() is deprecated in newer Mongoose versions. You can simplify your connection code to:
mongoose.connect('mongodb://localhost/peppino-calc') .then(() => console.log('MongoDB connected...')) .catch(err => console.log(err));
Mongoose now uses global Promises by default, so you don't need mongoose.Promise = global.Promise anymore.
内容的提问来源于stack exchange,提问作者Assaf petronio

