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

使用Express的sendFile时,如何将Token传递给客户端供后续请求复用?

解决方案:在Express中传递Bearer Token给客户端

嘿,这个需求其实挺常见的,我来给你捋几个靠谱的实现方式,都是我在实际项目里验证过的:

方法1:用模板引擎动态注入Token(最直接)

你现在用sendFile返回静态HTML,没法动态修改内容,所以可以换成模板引擎(比如EJS、Pug)来渲染页面,把Token直接嵌入到前端JS里。

步骤:

  1. 安装模板引擎(以EJS为例):
npm install ejs
  1. 配置Express使用模板引擎:
const express = require('express');
const app = express();

// 设置模板引擎为EJS
app.set('view engine', 'ejs');
// 设置模板文件所在目录(默认是views文件夹)
app.set('views', './views');
  1. 把你的静态HTML文件改成.ejs模板,在合适的位置注入Token:
<!-- views/index.ejs -->
<!DOCTYPE html>
<html>
<head>
  <title>My App</title>
</head>
<body>
  <script>
    // 从模板变量获取Token,并存到localStorage方便后续Axios使用
    const authToken = '<%= authToken %>';
    if (authToken) {
      localStorage.setItem('apiAuthToken', authToken);
    }

    // 后续Axios请求时自动带上Token
    axios.interceptors.request.use(config => {
      const token = localStorage.getItem('apiAuthToken');
      if (token) {
        config.headers.Authorization = `Bearer ${token}`;
      }
      return config;
    });
  </script>
</body>
</html>
  1. 修改路由,从请求头提取Token并渲染模板:
app.get('/', (req, res) => {
  // 从Authorization头提取Bearer Token(注意去掉"Bearer "前缀)
  const bearerToken = req.headers.authorization?.split(' ')[1];
  // 渲染模板并传递Token变量
  res.render('index', { authToken: bearerToken });
});

方法2:通过Cookie传递Token(适合跨页面共享)

如果希望Token在多个页面间共享,或者需要更规范的持久化存储,可以用Cookie传递(注意如果前端需要直接访问Token,不能设置HttpOnly属性):

后端代码:

const path = require('path');

app.get('/', (req, res) => {
  const bearerToken = req.headers.authorization?.split(' ')[1];
  if (bearerToken) {
    // 设置Cookie,生产环境记得开启secure和sameSite属性
    res.cookie('apiAuthToken', bearerToken, {
      httpOnly: false, // 必须设为false,否则前端JS无法读取
      secure: process.env.NODE_ENV === 'production', // 生产环境强制HTTPS传输
      sameSite: 'strict', // 防范CSRF攻击
      maxAge: 24 * 60 * 60 * 1000 // 过期时间设为1天
    });
  }
  // 继续返回你的静态HTML文件
  res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

前端代码:

// 从Cookie中提取Token的工具函数
function getCookie(name) {
  const value = `; ${document.cookie}`;
  const parts = value.split(`; ${name}=`);
  if (parts.length === 2) return parts.pop().split(';').shift();
}

// 提取Token并配置Axios
const authToken = getCookie('apiAuthToken');
if (authToken) {
  axios.defaults.headers.common.Authorization = `Bearer ${authToken}`;
}

方法3:通过自定义响应头传递(无侵入式)

如果不想修改HTML结构或引入模板引擎,还可以通过自定义响应头把Token传给前端,然后前端在页面加载时主动获取:

后端代码:

const path = require('path');

app.get('/', (req, res) => {
  const bearerToken = req.headers.authorization?.split(' ')[1];
  if (bearerToken) {
    // 设置自定义响应头
    res.set('X-Auth-Token', bearerToken);
  }
  res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

前端代码:

// 页面加载完成后,发送HEAD请求获取响应头
window.addEventListener('load', async () => {
  try {
    const response = await fetch(window.location.href, { method: 'HEAD' });
    const authToken = response.headers.get('X-Auth-Token');
    if (authToken) {
      localStorage.setItem('apiAuthToken', authToken);
      // 配置Axios自动携带Token
      axios.defaults.headers.common.Authorization = `Bearer ${authToken}`;
    }
  } catch (err) {
    console.error('获取认证Token失败:', err);
  }
});

安全提示

  • 生产环境必须启用HTTPS:防止Token在传输过程中被窃听
  • 不要将Token直接暴露在全局变量中,优先存储到localStorage或sessionStorage
  • 使用Cookie时,secure属性一定要在生产环境开启,确保仅通过HTTPS传输
  • 给Token设置合理的过期时间,避免长期有效带来的安全风险

内容的提问来源于stack exchange,提问作者Darren

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:04:25