You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于HTML、JS、Flask与MySQL的多步骤问卷实现求助

多步骤问卷优化:前端控流程+单次后端查询方案

问题概况

我正在开发一款3步骤的企业匹配问卷:

  • 步骤1:单选企业类别(radio按钮)
  • 步骤2:多选所需功能(checkbox)
  • 步骤3:单选集成需求(radio按钮)

用户完成问卷后,系统需从MySQL数据库中筛选符合所选条件的企业名称返回。当前实现尝试用每一步的用户输入生成SQL查询,以此动态加载下一步选项,但存在两个核心问题:

  1. 必须提交完整问卷才会触发后续查询,流程割裂
  2. 数据库响应延迟时,后续步骤的选项无法正常加载

希望改用JavaScript控制多步骤逻辑,最后仅执行一次数据库查询,求具体实现方案,附当前App.py和index.html代码。

实现方案

1. 前端:用JS接管步骤切换,统一收集参数后提交

核心思路是把所有步骤的DOM元素放在页面中,通过JS控制显示/隐藏,全程不向后端提交中间数据,最后一次性发送完整参数。

前端代码修改(index.html)

<!-- 步骤容器 -->
<div class="step-container">
  <div class="step active" id="step1">
    <h3>选择企业类别</h3>
    <label><input type="radio" name="category" value="SaaS"> SaaS</label>
    <label><input type="radio" name="category" value="OnPrem"> 本地部署</label>
    <button onclick="switchStep(2)">下一步</button>
  </div>

  <div class="step" id="step2">
    <h3>选择所需功能</h3>
    <label><input type="checkbox" name="features" value="CRM"> CRM</label>
    <label><input type="checkbox" name="features" value="Analytics"> 数据分析</label>
    <button onclick="switchStep(1)">上一步</button>
    <button onclick="switchStep(3)">下一步</button>
  </div>

  <div class="step" id="step3">
    <h3>选择集成需求</h3>
    <label><input type="radio" name="integration" value="API"> API集成</label>
    <label><input type="radio" name="integration" value="NoIntegration"> 无需集成</label>
    <button onclick="switchStep(2)">上一步</button>
    <button onclick="submitQuery()">提交查询</button>
  </div>
</div>

<!-- 结果展示区 -->
<div id="result"></div>

<style>
.step { display: none; }
.step.active { display: block; }
</style>

<script>
function switchStep(targetStep) {
  // 切换步骤显示状态
  document.querySelectorAll('.step').forEach(step => step.classList.remove('active'));
  document.getElementById(`step${targetStep}`).classList.add('active');
}

function submitQuery() {
  // 收集所有选中的参数
  const selectedCategory = document.querySelector('input[name="category"]:checked')?.value;
  const selectedFeatures = Array.from(document.querySelectorAll('input[name="features"]:checked')).map(el => el.value);
  const selectedIntegration = document.querySelector('input[name="integration"]:checked')?.value;

  // 参数校验(可选,避免空提交)
  if (!selectedCategory || selectedFeatures.length === 0 || !selectedIntegration) {
    alert('请完成所有步骤的选择');
    return;
  }

  // 显示加载状态
  const resultDiv = document.getElementById('result');
  resultDiv.innerHTML = '<p>正在查询...</p>';

  // 发送AJAX请求到后端
  fetch('/submit-query', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      category: selectedCategory,
      features: selectedFeatures,
      integration: selectedIntegration
    })
  })
  .then(res => res.json())
  .then(data => {
    // 渲染查询结果
    if (data.companies.length === 0) {
      resultDiv.innerHTML = '<p>未找到匹配的企业</p>';
    } else {
      resultDiv.innerHTML = `
        <h3>匹配的企业</h3>
        <ul>${data.companies.map(company => `<li>${company}</li>`).join('')}</ul>
      `;
    }
  })
  .catch(err => {
    resultDiv.innerHTML = '<p>查询失败,请稍后重试</p>';
    console.error(err);
  });
}
</script>

2. 后端:接收完整参数,执行单次SQL查询

后端只需提供一个接收POST请求的接口,拿到所有参数后执行一次筛选查询,返回结果即可。

后端代码修改(App.py)

from flask import Flask, request, jsonify
import mysql.connector

app = Flask(__name__)

# 数据库配置(替换为你的实际配置)
DB_CONFIG = {
    'user': 'your_db_user',
    'password': 'your_db_pwd',
    'host': 'localhost',
    'database': 'your_db_name'
}

@app.route('/submit-query', methods=['POST'])
def submit_query():
    try:
        # 获取前端发送的参数
        req_data = request.get_json()
        category = req_data.get('category')
        features = req_data.get('features', [])
        integration = req_data.get('integration')

        # 构建参数化SQL查询(避免SQL注入)
        query = """
            SELECT company_name 
            FROM companies 
            WHERE category = %s 
              AND integration_requirement = %s
              AND feature IN ({})
        """.format(', '.join(['%s'] * len(features)))
        
        # 执行查询
        conn = mysql.connector.connect(**DB_CONFIG)
        cursor = conn.cursor()
        cursor.execute(query, [category, integration] + features)
        companies = [row[0] for row in cursor.fetchall()]

        cursor.close()
        conn.close()

        return jsonify({'companies': companies})
    except Exception as e:
        print(f"查询错误: {e}")
        return jsonify({'error': '查询失败'}), 500

if __name__ == '__main__':
    app.run(debug=True)

核心注意事项

  • SQL注入防护:必须使用参数化查询,绝对不能直接拼接用户输入到SQL语句中
  • 前端体验优化:添加步骤切换动画、提交时的加载状态,以及错误提示,提升用户体验
  • 参数校验:前端和后端都要做参数校验,避免空值或非法参数导致查询出错

内容的提问来源于stack exchange,提问作者h1917

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 13:45:31