You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,适配页面跳转场景

这种方案符合服务端渲染页面的访问逻辑,不需要修改页面跳转的交互:

  1. 安装cookie-parser中间件,用于读取请求携带的Cookie
  2. 调整auth校验中间件,同时支持从请求头和Cookie中获取token,针对页面访问请求无token时直接重定向到登录页,而非返回JSON
  3. 用户登录成功后,将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 22:36:03