Flask返回HTML但浏览器不渲染页面问题排查求助
问题分析与解决方案
核心原因:Fetch请求未处理返回内容
你用fetch发送请求后,仅在控制台打印了返回的HTML,没有将其渲染到浏览器页面中,这就是为什么只能在控制台看到代码、页面无变化的根本原因。
其他潜在问题及修复方案
1. 按钮ID重复,仅第一个按钮生效
表格内所有按钮使用了同一个id="seePage",document.getElementById仅能获取第一个按钮,其余按钮点击无响应。需改用class标识按钮,或通过事件委托处理动态元素。
2. 冗余的form标签
每个按钮外层的form标签完全无用,既无提交逻辑也未用到其属性,直接删除即可。
3. 每次请求重复触发Google授权
/image路由内每次请求都会重新执行Google授权流程,体验极差。应将授权逻辑移至Flask启动时执行一次,缓存credentials。
4. 搜索函数的冗余判断与重复调用
search_word内重复判断if word in row,且search函数两次调用search_word(search_query),造成资源浪费。
修改后的代码示例
搜索结果页面Python代码
@app.route('/search', methods=['GET']) def search(): search_query = request.args.get('search_query') def search_word(word): l_rows = [] for idx, row in enumerate(df.text): # 跳过空白行(float类型代表NaN) if not isinstance(row, float) and word in row: # 用class代替id,通过data-id存储图片ID,删除冗余form btn_html = f'<button class="see-page-btn" data-id="{df.loc[idx, "id"]}">{df.loc[idx, "id"]}</button>' d_rows = { "id": btn_html, "period": df.loc[idx, "period"], "committee": df.loc[idx, "comitee"] # 注意原代码拼写为comitee,请确认是否为笔误 } l_rows.append(d_rows) new_df = pd.DataFrame.from_dict(l_rows) return new_df.to_html(classes='my-table', border=1, escape=False) # 仅调用一次搜索函数,避免重复计算 html_table = search_word(search_query) return render_template("search_results.html", table=html_table)
搜索结果页面HTML代码
<!DOCTYPE html> <html> <title>Search Results</title> <head> <style> .my-table { border-collapse: collapse; margin: 20px 0; } .my-table th, .my-table td { border: 1px solid #ddd; padding: 8px; } .see-page-btn { padding: 5px 10px; cursor: pointer; } </style> </head> <body> <div> {{table|safe}} </div> <script> // 用事件委托处理动态生成的按钮 document.addEventListener('click', function(e) { if (e.target.classList.contains('see-page-btn')) { const imageId = e.target.dataset.id; const data = new URLSearchParams(); data.append("buttonText", imageId); // 方案1:在当前页面插入图片内容 fetch("/image", { method: "POST", body: data }) .then(response => response.text()) .then(html => { // 创建新容器插入页面尾部 const container = document.createElement('div'); container.innerHTML = html; document.body.appendChild(container); }) .catch(err => console.error('请求失败:', err)); // 方案2:打开新窗口显示图片页面(更符合用户预期,推荐使用) // const form = document.createElement('form'); // form.method = 'POST'; // form.action = '/image'; // form.target = '_blank'; // const input = document.createElement('input'); // input.type = 'hidden'; // input.name = 'buttonText'; // input.value = imageId; // form.appendChild(input); // document.body.appendChild(form); // form.submit(); // document.body.removeChild(form); } }); </script> </body> </html>
图片页面Python代码
# 将授权逻辑移至路由外部,启动Flask时仅执行一次 from google_auth_oauthlib.flow import InstalledAppFlow import requests SCOPES = ['https://www.googleapis.com/auth/drive.readonly'] CLIENT_SECRET_FILE = 'cred_2.json' FOLDER_ID = 'your-folder-id-here' # 单独提取文件夹ID,便于维护 # 初始化Google Drive授权 flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRET_FILE, SCOPES, redirect_uri='http://127.0.0.1:5000') credentials = flow.run_local_server(port=0) @app.route('/image', methods=['GET', 'POST']) def image_display(): cell_value = request.form.get('buttonText') if not cell_value: return '请提供图片ID' def get_image(image_id): access_token = credentials.token headers = {'Authorization': f'Bearer {access_token}'} # 使用f-string拼接URL,可读性更强 url = f'https://www.googleapis.com/drive/v3/files?q=name="{image_id.strip()}.jpg"+and+parents="{FOLDER_ID}"' response = requests.get(url, headers=headers) data = response.json() try: file_id = data['files'][0]['id'] return f'https://drive.google.com/uc?id={file_id}' except IndexError: return None image_url = get_image(cell_value) if image_url: return render_template('image.html', cell_value=cell_value, image_url=image_url) else: return render_template('image.html', cell_value=cell_value, error_message='未找到匹配的图片')
图片页面HTML代码(可直接复用)
<!DOCTYPE html> <html> <head> <title>Page Image</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <h1>ImageId: {{ cell_value }}</h1> {% if image_url %} <img src="{{ image_url }}" alt="{{ cell_value }}" style="max-width: 100%;"> {% endif %} {% if error_message %} <p class="error" style="color: red;">{{ error_message }}</p> {% endif %} </body> </html>
内容的提问来源于stack exchange,提问作者KostasBar
相关产品推荐
相关产品推荐

