Express/Node.js中EJS模板能否在链接传请求头?JWT认证GET如何传token
问题1:EJS模板中普通链接能否传递自定义请求头
不能。
普通<a>标签跳转、浏览器地址栏访问这类原生导航请求,是浏览器默认发起的,不支持自定义请求头,该限制和模板引擎无关,无论使用EJS还是其他服务端渲染模板都无法突破。仅XHR、fetch等AJAX请求支持手动配置自定义请求头。
问题2:fetch请求携带token后无法正常重定向渲染页面的解决方案
问题原因
你通过fetch发起的是AJAX异步请求,即使服务端返回渲染后的HTML内容或重定向响应,fetch只会将响应内容作为普通数据返回,不会自动触发浏览器的页面渲染或跳转行为。Postman测试正常是因为Postman会直接展示响应的HTML内容,和浏览器的AJAX请求逻辑不同。
可行方案
方案1(推荐):使用Cookie存储JWT,适配页面跳转场景
这种方案符合服务端渲染页面的访问逻辑,不需要修改页面跳转的交互:
- 安装
cookie-parser中间件,用于读取请求携带的Cookie - 调整auth校验中间件,同时支持从请求头和Cookie中获取token,针对页面访问请求无token时直接重定向到登录页,而非返回JSON
- 用户登录成功后,将JWT写入HttpOnly Cookie,避免XSS攻击风险
修改后的auth.js代码示例:
async function (req, res, next) { // 同时兼容请求头传token(AJAX场景)和Cookie传token(页面跳转场景) const token = req.header('x-auth-token') || req.cookies.x_auth_token; if (!token) { // 判断请求是否是页面访问,是则直接跳登录页 if (req.accepts('html')) return res.redirect('/login'); return res.status(401).json({ msg: 'Forbidden' }); } try { const decoded = jwt.verify(token, process.env.TOKEN_SECRET); req.user = decoded.user; next(); } catch (e) { if (req.accepts('html')) return res.redirect('/login'); return res.status(401).json({ err: 'fail' }); } };
方案2:保持请求头传token,前端手动处理fetch响应
如果不想改动token的传递方式,前端fetch请求时需要手动配置头信息,拿到响应的HTML内容后手动渲染到页面:
// 前端fetch请求示例 fetch('/person', { headers: { 'x-auth-token': 本地存储的token } }) .then(res => res.text()) .then(html => { // 手动替换当前页面内容 document.documentElement.innerHTML = html; // 如需修改地址栏url可配合history API使用 })
该方案会破坏浏览器的前进后退历史记录,不推荐常规页面跳转场景使用。
方案3(不推荐):将token放在URL query参数中传递
直接在普通链接的URL后拼接?token=xxx,服务端auth中间件增加从query中取token的逻辑即可。但该方案会导致token泄露在浏览器历史、服务端日志中,安全性极低,仅可用于临时调试场景。
内容的提问来源于stack exchange,提问作者E-M-C
相关产品推荐
相关产品推荐

