React(Gatsby)应用读取.env配置调用API失效问题
读取.env配置时API无法正常工作的核心原因
- 环境变量名拼写不匹配:代码中请求API地址读取的变量是
process.env.REACT_APP_DATAS_API,但.env文件中定义的API地址变量名是REACT_APP_PROJECTS_API,二者名称完全不一致,读取结果为undefined,直接导致fetch请求无有效目标地址。 - 框架环境变量前缀使用错误:你当前使用的是Gatsby框架,不是Create React App搭建的原生React项目。Gatsby框架约定,客户端侧可访问的环境变量必须以
GATSBY_为前缀,你使用的REACT_APP_是Create React App的专属前缀,Gatsby不会把这类变量注入到客户端JS bundle中,组件代码里读取这类变量统一返回undefined。 - env文件路径匹配错误:你在gatsby-config中配置dotenv的读取路径为
.env.${process.env.NODE_ENV},开发环境下该路径对应.env.development、生产环境对应.env.production,但你当前存放配置的文件命名为.env,没有对应环境后缀,dotenv根本不会加载这个文件的配置。 - 代码存在隐性逻辑bug:
myHeaders实例定义在getDatas函数外层的组件作用域,每次触发getDatas执行都会重复向同一个Headers实例追加请求头,多次调用后请求头会出现重复字段,即使环境变量配置正确,后续请求也可能被服务端拦截。
对应修复方案
- 调整env文件命名与加载逻辑:开发环境将配置文件改名为
.env.development放在项目根目录,生产环境改名为.env.production;如果需要保留通用.env文件,修改gatsby-config中的dotenv配置,增加对通用配置的加载:
require("dotenv").config({ path: `.env.${process.env.NODE_ENV}` }); // 加载通用.env配置,优先级低于环境专属配置 require("dotenv").config({ path: `.env`, override: false });
- 统一修改环境变量规则:将所有需要在客户端组件中访问的环境变量前缀改为
GATSBY_,同时修正变量名拼写不一致的问题,修改后的.env配置示例:
GATSBY_DATAS_API=https://this-is-the-api-uri GATSBY_ACCESS_CONTROL=this-is-the-access-control GATSBY_BEARER=Bearer this-is-the-bearer-token
- 修正组件代码:同步替换代码中读取的环境变量名,同时把Headers实例移到
getDatas函数内部,避免重复追加请求头:
const [data, setDatas] = useState() const getDatas = async () => { // 每次调用生成新的Headers实例,避免头信息重复叠加 let myHeaders = new Headers(); myHeaders.append("Access-Control-Request-Headers", process.env.GATSBY_ACCESS_CONTROL); myHeaders.append("Authorization", process.env.GATSBY_BEARER); const requestOptions = { method: 'GET', headers: myHeaders, redirect: 'follow' }; try { let response = await fetch( process.env.GATSBY_DATAS_API, requestOptions); let result = await response.json(); setDatas(result) } catch (err) { console.error(err); } };
- 重启开发服务:环境变量的加载发生在服务启动阶段,修改配置后必须重启Gatsby服务才能生效,热更新不会读取新的环境变量值。
内容的提问来源于stack exchange,提问作者iamaprogrammer
相关产品推荐
相关产品推荐

