使用dotenv隐藏API_KEY时出现window/document未定义的ReferenceError求助
问题原因及解决办法
为什么会出现这个错误?
你用的dotenv是给Node.js后端设计的模块,它依赖Node环境特有的process全局对象,但浏览器里根本没有这个东西。当你在浏览器脚本里导入dotenv时,模块执行会报错,进而打乱后续代码的执行上下文,最终触发window/document未定义的错误——本质不是window真的不存在,而是模块加载失败导致执行流程出了问题。
怎么解决?
推荐方案:用构建工具注入环境变量
如果你的项目用了Vite、Webpack这类构建工具,它们本身就支持环境变量注入,完全不需要dotenv:
- 在项目根目录创建
.env文件,写入VITE_API_KEY=你的API密钥(Vite要求前缀必须是VITE_,Webpack可自定义前缀) - 代码里直接用
import.meta.env.VITE_API_KEY(Vite)或process.env.API_KEY(Webpack需配置DefinePlugin) - 构建工具会在打包时把环境变量替换成实际值,浏览器能正常读取,且
.env文件不会被打包,安全又方便
无构建工具的方案
要是不想用构建工具,别碰dotenv,换个简单方式:
- 新建
config.js文件存储密钥:
export const API_KEY = '你的API密钥';
- 在主脚本里导入变量:
import { API_KEY } from './config.js';
- 把
config.js加入.gitignore,避免密钥提交到代码仓库
额外修复:DOM加载时机问题
你的代码一开始就直接获取input的值,如果脚本在DOM渲染完成前加载,会获取不到元素。把所有操作DOM的代码放到DOM加载完成的回调里:
document.addEventListener('DOMContentLoaded', () => { // 所有DOM操作逻辑都写在这里 });
修正后的完整代码示例(Vite环境)
const API_KEY = import.meta.env.VITE_API_KEY; document.addEventListener('DOMContentLoaded', () => { const input = document.querySelector('input'); const button = document.querySelector('button'); button.addEventListener('click', () => { const choice = input.value; const URL = `https://api.nasa.gov/planetary/apod?api_key=${API_KEY}&date=${choice}`; fetch(URL) .then(res => res.json()) .then(data => { console.log(data); const hdImg = document.querySelector('#hd'); const iframe = document.querySelector('iframe'); const title = document.querySelector('#title'); const explanation = document.querySelector('h3'); if (data.media_type === 'image') { hdImg.src = data.hdurl; hdImg.style.display = 'block'; iframe.style.display = 'none'; } else if (data.media_type === 'video') { iframe.src = data.url; iframe.style.display = 'block'; hdImg.style.display = 'none'; } else { alert('Media Not Supported - Contact NASA Immediately'); } title.innerText = data.title; explanation.innerText = data.explanation; }) .catch(err => { console.log(`error ${err}`); }); }); });
内容的提问来源于stack exchange,提问作者bpkush
相关产品推荐
相关产品推荐

