Node.js中res.redirect()后调用res.send()及重定向传参问题
嘿,我来帮你理清楚这两个问题,都是新手刚接触Express时容易踩的坑~
第一个问题:res.redirect()之后能调用res.send()吗?
答案是绝对不行!
因为HTTP协议规定,一个请求只能对应一个完整的响应。当你调用res.redirect()时,Express已经向客户端发送了3xx的状态码(比如302)和Location响应头,这时候整个响应已经结束了。如果之后再调用res.send(),Node.js会直接报错,提示你“Cannot set headers after they are sent to the client”——简单说就是响应已经发出去了,没法再补内容啦。
所以一定要记住:一个请求里,res.redirect()和res.send()只能二选一,不能同时用。
第二个问题:怎么把postcode传递到重定向后的app.get()路由里?
给你推荐几个适合新手的简单方案,根据你的需求选就行:
方案1:通过URL查询参数传递(最直观,适合非敏感数据)
直接把postcode拼到重定向的URL后面,作为查询参数,后续路由通过req.query获取:
// 源路由(比如处理表单提交的post请求) app.post('/submit-postcode', (req, res) => { const postcode = req.body.postcode; // 假设从表单body里拿到邮编 // 重定向到目标页面,把postcode拼在URL里(用encodeURIComponent处理特殊字符) res.redirect(`/result-page?postcode=${encodeURIComponent(postcode)}`); }); // 目标路由(接收postcode的get请求) app.get('/result-page', (req, res) => { // 从query里取出postcode const postcode = req.query.postcode; // 接下来就可以用这个postcode做你需要的操作啦 res.send(`你提交的邮编是:${postcode}`); });
这个方法的缺点是邮编会显示在浏览器地址栏里,所以如果是敏感数据就别用这个。
方案2:通过Session传递(适合敏感数据)
如果不想把postcode暴露在URL里,可以用Express的Session中间件,把数据存在服务器端的会话里:
首先安装依赖:
npm install express-session
然后在你的Express项目里配置Session:
const express = require('express'); const session = require('express-session'); const app = express(); // 配置session app.use(session({ secret: 'your-own-secret-key', // 换成一个自己的随机字符串,用来加密session resave: false, saveUninitialized: true, cookie: { secure: false, // 生产环境如果用HTTPS的话改成true maxAge: 3600000 // session有效期1小时,可按需调整 } })); // 解析表单body(如果是从表单拿postcode的话需要这个) app.use(express.urlencoded({ extended: true }));
然后在源路由存session,重定向后再取:
// 源路由 app.post('/submit-postcode', (req, res) => { const postcode = req.body.postcode; // 把postcode存到session里 req.session.postcode = postcode; // 重定向到目标页面 res.redirect('/result-page'); }); // 目标路由 app.get('/result-page', (req, res) => { // 从session里取出postcode const postcode = req.session.postcode; // 用完最好删掉,避免残留 delete req.session.postcode; if (postcode) { res.send(`你提交的邮编是:${postcode}`); } else { res.send('没有获取到邮编哦'); } });
Session的数据存在服务器端,客户端只会拿到一个session id的cookie,所以数据不会暴露,适合敏感信息。
方案3:一次性Flash消息(可选,适合临时数据)
如果只是想传递一次性的提示或数据,可以用express-flash模块(本质也是基于Session),数据取一次就自动销毁,适合提示类场景,用法和Session类似,你可以按需了解~
内容的提问来源于stack exchange,提问作者M.Asgari

