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

Node.js Express如何将process.env.API_KEY传递给公共app.js

解决方案

首先明确:public目录下的app.js运行在用户浏览器环境,不存在Node.js的process对象,无法直接读取后端的process.env变量,必须由后端主动把值传递给前端。
重要提醒:如果你的API_KEY是付费、带调用权限的私密服务端密钥,绝对不要直接传到前端——所有访问站点的用户都能通过浏览器开发者工具拿到这个密钥,很容易被盗用刷取接口额度。这种场景请把需要用到密钥的第三方API调用逻辑放到后端,前端仅请求你自己的服务端接口即可。如果该密钥本身就是设计给前端使用的可公开公钥,可使用下面两种方案传递。


方案1:HTML注入全局变量(适合公钥场景)

在返回首页HTML时把密钥注入到页面全局变量,前端JS直接读取即可。

  1. 修改后端index.js代码,调整中间件顺序(符合Express最佳实践),增加首页注入逻辑:
const express = require('express');
const fs = require('fs');
const app = express();
require('dotenv').config();

const PORT = 3000;
// 先注册静态资源托管
app.use(express.static('public'));

// 单独处理首页路由,替换占位符注入密钥
app.get('/', (req, res) => {
  let html = fs.readFileSync('./public/index.html', 'utf-8');
  html = html.replace(
    '<!--API_KEY_INJECT-->',
    `<script>window.API_KEY = "${process.env.API_KEY}"</script>`
  );
  res.send(html);
})

app.listen(PORT, () => console.log(`Starting server: http://localhost:${PORT}`));
  1. 打开public/index.html,在引入app.js的标签前加上占位符:
<!-- 其他页面内容 -->
<!--API_KEY_INJECT-->
<script src="/app.js"></script>
  1. 前端app.js直接读取全局变量即可使用:
document.addEventListener('readystatechange', (event) => {
    if (event.target.readyState === 'complete') {
        initApp();
    }
});

const initApp = () => {
  // 直接读取window.API_KEY使用
  console.log('获取到的API_KEY:', window.API_KEY);
}

方案2:后端提供配置接口(适合公钥场景)

单独写一个返回公开配置的接口,前端初始化时先请求配置再启动逻辑。

  1. 后端增加配置接口:
const express = require('express');
const app = express();
require('dotenv').config();

const PORT = 3000;
app.use(express.static('public'));

// 仅返回可公开的配置项
app.get('/api/get-config', (req, res) => {
  res.json({
    apiKey: process.env.API_KEY
  })
})

app.listen(PORT, () => console.log(`Starting server: http://localhost:${PORT}`));
  1. 前端app.js启动前先拉取配置:
document.addEventListener('readystatechange', async (event) => {
    if (event.target.readyState === 'complete') {
        // 先拉取公钥配置
        const configRes = await fetch('/api/get-config');
        const config = await configRes.json();
        window.API_KEY = config.apiKey;
        initApp();
    }
});

const initApp = () => {
  console.log('获取到的API_KEY:', window.API_KEY);
}

方案3:私密密钥的标准处理方式(推荐)

如果密钥不能公开,全程不要把密钥传到前端,所有需要用到密钥的请求都由后端代理转发:

  1. 后端封装代理接口,请求第三方服务时在服务端带上密钥:
const express = require('express');
const app = express();
const axios = require('axios'); // 需提前安装axios依赖
require('dotenv').config();

const PORT = 3000;
app.use(express.static('public'));

// 代理第三方API请求
app.get('/api/xxx-service', async (req, res) => {
  try {
    // 从query里拿前端传的业务参数
    const { param1 } = req.query;
    // 服务端请求第三方接口时带密钥,不会暴露给前端
    const thirdRes = await axios.get(`https://third-party-service.com/api`, {
      params: { param1, key: process.env.API_KEY }
    });
    res.json(thirdRes.data);
  } catch (err) {
    res.status(500).json({ msg: '请求失败' });
  }
})

app.listen(PORT, () => console.log(`Starting server: http://localhost:${PORT}`));
  1. 前端app.js直接请求自己的后端接口即可,全程不需要接触密钥:
document.addEventListener('readystatechange', (event) => {
    if (event.target.readyState === 'complete') {
        initApp();
    }
});

const initApp = async () => {
  // 请求自己的后端接口,不需要传密钥
  const res = await fetch('/api/xxx-service?param1=test');
  const data = await res.json();
  console.log(data);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.08 16:15:17