Flask向外部JavaScript传变量失败:如何将文件名传入graph.js?
嘿,我懂你现在的困扰——想把Flask后端flask_app.py里的文件名传递给静态目录下的create-graph.js,但直接传变量行不通对吧?毕竟静态JS文件没法直接读取Flask的上下文变量。下面给你几个实用的方案,完全适配你的文件结构:
方案1:通过HTML模板注入全局变量
这是最直接的方法:先在模板index.html里把后端的文件名渲染成全局JS变量,再让create-graph.js读取这个变量。
第一步:修改flask_app.py,把文件名传到模板
from flask import Flask, render_template import pandas as pd app = Flask(__name__) @app.route('/') def index(): data_files = ["file1.xlsx", "file2.xlsx", "file3.xlsx"] cur = 0 # 读取Excel文件 df1 = pd.read_excel(f"data/{data_files[cur]}") # 生成对应的CSV文件名(和你原逻辑一致) target_csv = f"{data_files[cur][:10]}.csv" # 把CSV保存到templates/data(建议后续移到static/data,原因后面说) df1.to_csv(f"templates/data/{target_csv}", encoding='utf-8', index=False) # 将CSV文件名传递给模板 return render_template('index.html', csv_filename=target_csv)
第二步:在index.html中注入全局变量
一定要先注入变量,再引入create-graph.js,确保JS加载时变量已经存在:
<!DOCTYPE html> <html> <head> <title>Graph Dashboard</title> </head> <body> <div id="graph-container"></div> <!-- 注入全局JS变量 --> <script> // 从Flask模板渲染获取文件名,存在window对象上 window.csvFilename = "{{ csv_filename }}"; // 可选:直接生成完整的CSV路径,避免JS里拼接出错 window.csvFullPath = "{{ url_for('static', filename='data/' + csv_filename) }}"; </script> <!-- 引入你的图表JS文件 --> <script src="{{ url_for('static', filename='js/create-graph.js') }}"></script> </body> </html>
第三步:在create-graph.js中使用变量
// 直接读取全局变量 const csvPath = `/templates/data/${window.csvFilename}`; // 如果用了上面的完整路径,直接用window.csvFullPath即可 // 示例:用Papa Parse加载CSV生成图表(你可以换成自己的图表逻辑) Papa.parse(csvPath, { download: true, header: true, complete: function(results) { console.log('加载到的数据:', results.data); // 这里写你的图表生成代码 } });
方案2:通过Flask API接口动态获取文件名
如果不想用全局变量,也可以给后端加一个小接口,让JS主动请求获取文件名。
第一步:在flask_app.py中添加接口
@app.route('/api/get-csv-filename') def get_csv_filename(): data_files = ["file1.xlsx", "file2.xlsx", "file3.xlsx"] cur = 0 target_csv = f"{data_files[cur][:10]}.csv" # 返回JSON格式的文件名 return {"filename": target_csv}
第二步:在create-graph.js中请求接口
// 发送GET请求获取文件名 fetch('/api/get-csv-filename') .then(response => { if (!response.ok) throw new Error('请求失败'); return response.json(); }) .then(data => { const csvPath = `/templates/data/${data.filename}`; // 后续加载CSV、生成图表的逻辑和方案1一致 Papa.parse(csvPath, { download: true, header: true, complete: function(results) { console.log('加载到的数据:', results.data); } }); }) .catch(error => console.error('获取文件名出错:', error));
方案3:通过HTML元素的data属性传递
这种方式更优雅,适合把变量和页面元素绑定:
第一步:在index.html的元素上设置data属性
<div id="graph-container" data-csv-filename="{{ csv_filename }}"></div>
第二步:在create-graph.js中读取data属性
// 获取页面元素 const graphContainer = document.getElementById('graph-container'); // 读取data属性值 const csvFilename = graphContainer.dataset.csvFilename; const csvPath = `/templates/data/${csvFilename}`; // 后续图表生成逻辑...
重要提醒
建议你把生成的CSV文件移到static/data/目录下,而不是templates/data/——因为Flask默认templates目录是用来渲染模板的,静态资源放在static下更规范,也能避免一些访问权限问题。修改后的保存路径:
df1.to_csv(f"static/data/{target_csv}", encoding='utf-8', index=False)
对应的JS路径就可以用{{ url_for('static', filename='data/' + csv_filename) }}生成,更可靠。
内容的提问来源于stack exchange,提问作者user7476979
相关产品推荐
相关产品推荐

