Express.js调用res.redirect提示is not a function报错解决
问题根因
两个问题导致报错:
- 变量名冲突(变量遮蔽):你在
checkDatabase返回Promise的.then()回调里,把入参命名成了res,这个参数会覆盖外层Express路由传入的响应对象res。你打印出来的这个内层res实际是数据库查询返回的URL字符串(比如你打印的https://www.google.com),字符串类型的值自然不存在redirect方法,调用就会抛类型错误。 - Promise链写法错误:你直接把
checkDatabase()执行返回的Promise对象传给了connectDatabase.then(),但.then()要求传入的是函数类型的回调,这种写法会导致数据库连接逻辑和查询逻辑顺序失控,错误捕获也会出现遗漏。
修复方案
调整回调参数命名避免重名,修正Promise链式调用的写法,参考代码如下:
router.get('/r/:shortUrl', function(req, res) { connectDatabase .then(() => { // 等数据库连接完成后再执行查询,返回查询Promise供后续链式调用 return checkDatabase(req.params.shortUrl) }) .then(targetUrl => { // 这里的targetUrl是数据库返回的真实地址,没有和外层res重名 console.log('checkdatabase targetUrl => ' + targetUrl); // 此处调用的是外层Express响应对象的redirect方法,可正常执行 res.redirect(targetUrl); }) .catch(e => { console.error(e); res.redirect(307, '/home'); }) });
额外提示
写JavaScript异步回调时要注意避开同名变量遮蔽的问题,尤其是Express路由里常用的req、res这类变量名,给自定义回调参数命名时尽量用有业务含义的名字(比如上面的targetUrl),既能避免冲突,也能提升代码可读性。
内容的提问来源于stack exchange,提问作者Jonathan Fox
相关产品推荐
相关产品推荐

