Flask部署Heroku:Python与JavaScript读取环境变量的方法
解决Flask应用中Python和JavaScript共享环境变量的问题
嘿,这个坑我之前踩过!你遇到的require is not defined错误本质原因很明确:浏览器端运行的JavaScript根本不支持Node.js的require()语法,而且前端代码是在用户的浏览器里执行的,完全没法直接访问服务器上的.env文件。下面给你几个实用的解决方案,适配不同场景:
方案一:通过Flask模板把环境变量注入前端(最推荐)
这是最简单直接的方式,适合大部分Flask项目。核心思路是让后端Flask读取环境变量,然后把需要的变量传递给前端模板,再在模板里定义全局JS变量供你的脚本使用。
步骤1:Flask视图函数传递变量
from flask import Flask, render_template import os from dotenv import load_dotenv # 加载本地.env文件(本地开发用,Heroku上不需要这行,因为Heroku会自动加载配置的环境变量) load_dotenv() app = Flask(__name__) @app.route('/') def home(): # 只把前端需要的环境变量传过去,别把所有.env内容都暴露了! frontend_env = { 'API_BASE_URL': os.getenv('API_BASE_URL'), 'APP_NAME': os.getenv('APP_NAME') } return render_template('index.html', frontend_env=frontend_env)
步骤2:在HTML模板中注入全局变量
在你的模板文件(比如templates/index.html)里,在加载自定义JS脚本之前,添加一段<script>标签定义全局变量:
<!DOCTYPE html> <html> <head> <title>{{ frontend_env.APP_NAME }}</title> </head> <body> <!-- 页面内容 --> <!-- 先注入环境变量 --> <script> // 把后端传来的变量转为前端可用的全局对象 window.FRONTEND_ENV = { apiBaseUrl: "{{ frontend_env.API_BASE_URL }}", appName: "{{ frontend_env.APP_NAME }}" }; </script> <!-- 再加载你的自定义JS脚本 --> <script src="{{ url_for('static', filename='js/main.js') }}"></script> </body> </html>
步骤3:在JS脚本中使用变量
现在你可以在static/js/main.js里直接访问这个全局变量了:
console.log('应用名称:', window.FRONTEND_ENV.appName); console.log('API地址:', window.FRONTEND_ENV.apiBaseUrl);
方案二:用前端构建工具注入环境变量(适合有前端工程化的项目)
如果你的前端代码用了Webpack、Vite这类构建工具,可以在构建阶段直接把环境变量注入到JS代码里。
比如用Vite的话:
- 在项目根目录创建
.env文件,变量名要以VITE_开头:VITE_API_BASE_URL=https://api.example.com VITE_APP_NAME=My Flask App - 在前端JS中直接通过
import.meta.env访问:console.log(import.meta.env.VITE_API_BASE_URL);
构建工具会在打包时把这些变量替换成实际值,之后把打包好的静态文件放到Flask的static目录下即可。
方案三:Heroku平台的特殊配置
在Heroku上部署时,你不需要上传本地的.env文件,直接通过Heroku的配置管理来设置环境变量:
- 方法1:登录Heroku仪表盘,找到你的应用,进入「Settings」→「Config Vars」添加变量;
- 方法2:用Heroku CLI命令设置:
heroku config:set API_BASE_URL=https://api.example.com APP_NAME=My Flask App
之后Flask可以直接通过os.getenv()读取这些变量,再用方案一的方式传给前端即可。
重要提醒
绝对不要把敏感的密钥(比如API密钥、数据库密码)直接传给前端!前端代码是公开可查的,敏感信息必须留在后端,前端需要用到时,通过Flask的API接口间接调用,由后端去使用这些敏感变量。
内容的提问来源于stack exchange,提问作者Joshua




