Express配置带参数路由访问报Cannot GET错误排查
故障原因
该报错和安装lodash依赖无任何关联,核心问题是路由定义存在语法错误:你在定义/posts/:postName路由时,错误地将app.get()方法的右括号提前闭合在路径参数之后,后续的请求处理回调函数没有作为参数传入app.get(),Express框架根本没有注册这个带参数的路由,访问对应路径时自然返回Cannot GET错误。
错误写法的问题点:
// 错误:路径字符串后多写了一个右括号,直接结束了app.get()调用,后面的回调是无效孤立代码 app.get("/posts/:postName"), function (req, res) { let requestedTitle = req.params.postName; posts.forEach(function(post) { let storedTitle = post.title; if (storedTitle === requestedTitle) { console.log('match found'); } else { console.log('no match found'); } }); };
对比你查到的官方示例可以发现,app.get()需要把「路由路径」「请求处理回调」两个参数都放在方法的括号内部,你的写法把回调隔离在了方法调用之外,框架完全感知不到这段路由逻辑。
修复步骤
- 删除路由路径后多余的右括号,将回调函数移入
app.get()的参数列表中 - 补充路由的响应逻辑:你当前的路由代码仅在控制台打印日志,没有给客户端返回任何响应,即使路由注册成功,请求也会一直处于挂起状态
- 补全其他路由中未定义的变量,避免触发引用错误
修正后的完整路由代码参考:
const _ = require('lodash'); const express = require("express"); const bodyParser = require("body-parser"); const ejs = require("ejs"); const homeStartingContent = "text"; // 补全之前缺失的常量定义 const aboutContent = "About page content"; const contactContent = "Contact page content"; const app = express(); let posts = []; app.set('view engine', 'ejs'); app.use(bodyParser.urlencoded({extended: true})); app.use(express.static("public")); app.get("/", function(req, res) { res.render(__dirname + "/views/home.ejs", {homeStartingContent: homeStartingContent, posts: posts}); }); app.get('/about', (req, res) => { res.render('about', {aboutContent: aboutContent}); }); app.get('/contact', (req, res) => { res.render('contact', {contactContent: contactContent}); }); app.get('/compose', (req, res) => { res.render('compose'); }); app.post('/compose', (req, res) => { posts.push(req.body); console.log(posts) res.redirect('/') }); // 修正括号位置后的参数路由 app.get("/posts/:postName", function (req, res) { let requestedTitle = req.params.postName; let targetPost = null; posts.forEach(function(post) { let storedTitle = post.title; // 可以用你安装的lodash做大小写、格式统一的匹配,避免因为大小写差异匹配失败 if (_.kebabCase(storedTitle) === _.kebabCase(requestedTitle)) { console.log('match found'); targetPost = post; } else { console.log('no match found'); } }); // 必须返回响应给客户端 if (targetPost) { res.render("post", { postTitle: targetPost.title, postContent: targetPost.content }) } else { res.status(404).send("未找到对应文章"); } }); app.listen(3000, function() { console.log("Server started on port 3000"); });
额外说明
你之前误以为是安装lodash导致故障属于时间上的巧合:你大概率是在安装lodash的同一次代码修改中,不小心误输入了多余的右括号,和lodash依赖本身没有任何关系,即使移除lodash的引入语句,只要括号位置错误,该路由依然无法正常工作。
内容的提问来源于stack exchange,提问作者Stefan Stahuber
相关产品推荐
相关产品推荐

