如何在NodeJS+Express+Handlebars应用中自动返回404页面?
Hey there! Let me break down exactly how to set up that seamless 404 experience for your Node.js, Express, and Handlebars app—just like GitHub does when you hit a non-existent URL.
Key Concept First: Route Order Matters
Express matches routes in the order you define them. So your 404 handler must be the last one you add—otherwise, it'll override all your valid routes (like your homepage /). That's a common gotcha, so keep that in mind!
Step 1: Keep Your Existing Routes Intact
First, leave your existing routes (like your homepage) as they are. For example, in your routes/index.js:
const router = require('express').Router(); router.get('/', (req, res) => { res.render('index/index'); }); // Add all your other valid routes here first: // router.get('/dashboard', (req, res) => { res.render('dashboard'); }); // router.post('/submit-form', (req, res) => { /* Handle form submission */ }); module.exports = router;
Step 2: Add the 404 Handler (After All Routes)
Instead of using a router.get('/:ThisCouldBeAnything') (which only catches GET requests), use app.use() to catch all HTTP methods (GET, POST, PUT, DELETE, etc.) for unrecognized paths. This matches GitHub's behavior perfectly.
In your main app.js (or server.js):
const express = require('express'); const exphbs = require('express-handlebars'); const indexRouter = require('./routes/index'); const app = express(); // Configure Handlebars app.engine('handlebars', exphbs()); app.set('view engine', 'handlebars'); // Mount all your valid routes first app.use('/', indexRouter); // If you have other route files (like /users), mount those too before the 404 handler: // app.use('/users', usersRouter); // 404 Page Handler - This goes LAST! app.use((req, res) => { // Set the HTTP status code to 404 (important for search engines and clients) res.status(404); // Render your 404 Handlebars template res.render('errors/404'); }); // Start the server const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Server up and running on port ${PORT}`); });
Step 3: Create Your 404 Handlebars Template
Make sure you have a errors/404.handlebars file in your views directory. You can style it to match your app's design—here's a simple example inspired by GitHub:
<div class="container"> <h1>404</h1> <h2>Page not found</h2> <p>The URL you entered doesn't exist, or you don't have permission to access it.</p> <a href="/">Go back to homepage</a> </div>
Bonus: Handling Permission Denied (403)
You mentioned "no permission access"—that's a separate case from 404. For routes where users lack permissions, you can manually send a 403 status and render a dedicated 403 template:
router.get('/admin', (req, res) => { // Check if user is admin (example logic) if (!req.user.isAdmin) { res.status(403); return res.render('errors/403'); } // If authorized, render admin page res.render('admin/dashboard'); });
That's it! Now any unrecognized URL (regardless of HTTP method) will land on your 404 page, just like GitHub.
内容的提问来源于stack exchange,提问作者Roger

