Express中res.redirect()在POST/PUT路由下重定向路径异常问题
问题现象
两段代码预期重定向目标均为 products/:id,但实际传入res.redirect的路径写法存在差异:
- 挂载在
/路径的post路由中,重定向必须拼接products/前缀才能跳转到目标地址 - 挂载在
/:id路径的put路由中,不需要加该前缀,直接传入商品ID即可完成正确跳转
相关实现代码如下:
POST路由代码:
router.post("/", async (req, res) => { const newProduct = new Product(req.body) await newProduct.save() console.log(newProduct) res.redirect(`products/${newProduct.id}`) })
PUT路由代码:
router.put("/:id", async (req, res) => { const { id } = req.params const product = await Product.findByIdAndUpdate(id, req.body, { runValidators: true, new: true }) console.log(req.body) res.redirect(`${product._id}`) })
原因说明
这个现象的核心是Express中res.redirect对非根开头的相对路径,完全遵循标准URL相对路径解析规则:以当前请求的URL路径为基准,取当前路径最后一个/之前的部分作为目录基准,和传入的相对路径拼接生成最终跳转地址。
默认场景下这两段代码所属的路由实例,是挂载在站点/products路径前缀下的,我们可以分别对应两个路由的请求路径拆解解析逻辑:
- POST路由的匹配规则是
/,对应实际请求路径为/products(路径末尾无斜杠,最后一个/是根路径的斜杠,目录基准为/)。此时传入相对路径products/${newProduct.id},和基准路径拼接后最终得到/products/${newProduct.id},符合预期目标。 - PUT路由的匹配规则是
/:id,对应实际请求路径为/products/[当前商品ID](比如/products/123,路径末尾无斜杠,最后一个/在products和商品ID之间,目录基准为/products/)。此时传入相对路径${product._id},和基准路径拼接后最终得到/products/${product._id},刚好符合目标地址,因此不需要额外加前缀。
注意:这种依赖当前路径层级的相对路径写法容错性很差,只要路由挂载路径、请求路径格式变了就会出现跳转错误。生产环境推荐始终传入以
/开头的站点绝对路径,比如统一写为res.redirect(/products/${id}),完全不需要考虑当前路由的层级,不会出现解析偏差。
内容的提问来源于stack exchange,提问作者Nicolás Garitagoitia
相关产品推荐
相关产品推荐

