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

如何将JavaScript数组传递至Python Flask后端?

问题:Flask项目中JS数组数据传递到Python端失败

我不是JavaScript专家,正在做一个用Python Flask搭建网站的学校项目。现在遇到的问题是:HTML输入的值已经存入JavaScript数组(genre_list和keyword_list),但无法将这些数组数据传递到Python端处理。尝试使用XMLHttpRequest但效果不佳,以下是初始及修改后的相关代码:


初始代码

HTML

<html>
   <head>
      <title>4 Years</title>
      <meta name='viewport' content='width=device-width, initial-scale=1'>
      <script src="https://kit.fontawesome.com/7006f68f03.js" crossorigin="anonymous"></script>
      <link rel="stylesheet" href="static/category.css">
   </head>
   <body>
      <img src="static/test.jpeg" height="70">
      <hr>
      <form class="content" action="/category/list" method="post" id="myform">
         <div class="genres-input">
            Genres:
            <div class="genres-box">
               <ul id="genreul">
                  <input class="input-text" type="text" name="genres" list="genre">
               </ul>
               <datalist id="genre">
                  <option value="Action"></option>
                  <option value="Adventure"></option>
                  <option value="Animation"></option>
                  <option value="Biography"></option>
                  <option value="Comedy"></option>
                  <option value="Crime"></option>
                  <option value="Documentary"></option>
                  <option value="Drama"></option>
                  <option value="Family"></option>
                  <option value="Fantasy"></option>
                  <option value="Film-Noir"></option>
                  <option value="Game-Show"></option>
                  <option value="History"></option>
                  <option value="Horror"></option>
                  <option value="Music"></option>
                  <option value="Musical"></option>
                  <option value="Mystery"></option>
                  <option value="News"></option>
                  <option value="Reality-TV"></option>
                  <option value="Romance"></option>
                  <option value="Sci-Fi"></option>
                  <option value="Short"></option>
                  <option value="Sport"></option>
                  <option value="Talk-Show"></option>
                  <option value="Thriller"></option>
                  <option value="War"></option>
                  <option value="Western"></option>
               </datalist>
            </div>
         </div>
         <div class="age-input">
            Ages:
            <div class="ages-box">
               <input class="input-text" type="number" name="ages" placeholder=" 0 - 99" min="0" max="99">
            </div>
         </div>
         <div class="keywords-input">
            Keywords:
            <div class="keywords-box">
               <ul id="keyul">
                  <input class="input-text" type="text" name="keywords">
               </ul>
            </div>
         </div>
         <div class="type-input">
            Types:
            <div class="types-box">
               <input class="input-text" type="text" name="types" list="type">
               <datalist id="type">
                  <option value="Movie"></option>
                  <option value="TV Series"></option>
                  <option value="Short"></option>
                  <option value="TV Episode"></option>
                  <option value="TV Mini Series"></option>
                  <option value="TV Movie"></option>
                  <option value="TV Special"></option>
                  <option value="TV Short"></option>
                  <option value="Video Game"></option>
                  <option value="Video"></option>
                  <option value="Music Video"></option>
                  <option value="Podcast Series"></option>
                  <option value="Podcast Episode"></option>
            </div>
         </div>
         <div class="search">
            <input class="submit" onclick="search_value()" type="button" name="search" value="Search">
         </div>
      </form>
      <script src="static/category.js"></script>
      <script src="static/disable_enter.js"></script>
   </body>
</html>

JS

var ul1 = document.querySelector("ul#genreul"),
input1 = ul1.querySelector("input");
let genre_list = [];
var ul2 = document.querySelector("ul#keyul"),
input2 = ul2.querySelector("input");
let keyword_list = [];
function createTag1(){
   ul1.querySelectorAll("li#genres").forEach(li => li.remove());
   console.log(keyword_list.slice().reverse());
   genre_list.slice().reverse().forEach(genre =>{
      let liTag1 = `<li id='genres'>${genre} <i class="fa-solid fa-x" onclick="remove1(this,'${genre}')"></i></li>`;
      ul1.insertAdjacentHTML("afterbegin", liTag1);
   });
}
function createTag2(){
   ul2.querySelectorAll("li#keywords").forEach(li => li.remove());
   console.log(keyword_list.slice().reverse());
   keyword_list.slice().reverse().forEach(keyword =>{
      let liTag2 = `<li id='keywords'>${keyword} <i class="fa-solid fa-x" onclick="remove2(this,'${keyword}')"></i></li>`;
      ul2.insertAdjacentHTML("afterbegin", liTag2);
   });
}
function remove1(element, genre){
   let index1 = genre_list.indexOf(genre);
   genre_list = [...genre_list.slice(0, index1), ...genre_list.slice(index1 + 1)];
   element.parentElement.remove();
}
function remove2(element, keyword){
   let index2 = keyword_list.indexOf(keyword);
   keyword_list = [...keyword_list.slice(0, index2), ...keyword_list.slice(index2 + 1)];
   element.parentElement.remove();
}
function addTag1(e){
   if(e.key == "Enter"){
      let genre = e.target.value.replace(/\s+/g, ' ').replace(',','');
      if(genre.length > 1 && !genre_list.includes(genre)){
         genre_list.push(genre);
         createTag1();
      }
      e.target.value = "";
   }
}
function addTag2(e){
   if(e.key == "Enter"){
      let keyword = e.target.value.replace(/\s+/g, ' ').replace(',','');
      if(keyword.length > 1 && !keyword_list.includes(keyword)){
         keyword_list.push(keyword);
         createTag2();
      }
      e.target.value = "";
   }
}
function search_value() {
   console.log(genre_list);
   console.log(keyword_list);
   document.getElementById("myform").submit();
}
input1.addEventListener("keyup", addTag1);
input2.addEventListener("keyup", addTag2);

Python

from flask import Blueprint,request,render_template
Category = Blueprint('category',__name__,static_folder='static',template_folder='templates')
@Category.route('/category')
def category_html():return render_template('category.html')
@Category.route('/category/list',methods=['POST','GET'])
def category_value():
   #genre =
   ages = request.form["ages"]
   #keyword = 
   types = request.form['types']
   print(ages,types)
   return render_template('list.html',text2=ages,text4=types)

修改后的代码

JS

var ul1 = document.querySelector("ul#genreul"),
input1 = ul1.querySelector("input");
let genre_list = [];
var ul2 = document.querySelector("ul#keyul"),
input2 = ul2.querySelector("input");
let keyword_list = [];
function createTag1(){
   ul1.querySelectorAll("li#genres").forEach(li => li.remove());
   console.log(keyword_list.slice().reverse());
   genre_list.slice().reverse().forEach(genre =>{
      let liTag1 = `<li id='genres'>${genre} <i class="fa-solid fa-x" onclick="remove1(this,'${genre}')"></i></li>`;
      ul1.insertAdjacentHTML("afterbegin", liTag1);
   });
}
function createTag2(){
   ul2.querySelectorAll("li#keywords").forEach(li => li.remove());
   console.log(keyword_list.slice().reverse());
   keyword_list.slice().reverse().forEach(keyword =>{
      let liTag2 = `<li id='keywords'>${keyword} <i class="fa-solid fa-x" onclick="remove2(this,'${keyword}')"></i></li>`;
      ul2.insertAdjacentHTML("afterbegin", liTag2);
   });
}
function remove1(element, genre){
   let index1 = genre_list.indexOf(genre);
   genre_list = [...genre_list.slice(0, index1), ...genre_list.slice(index1 + 1)];
   element.parentElement.remove();
}
function remove2(element, keyword){
   let index2 = keyword_list.indexOf(keyword);
   keyword_list = [...keyword_list.slice(0, index2), ...keyword_list.slice(index2 + 1)];
   element.parentElement.remove();
}
function addTag1(e){
   if(e.key == "Enter"){
      let genre = e.target.value.replace(/\s+/g, ' ').replace(',','');
      if(genre.length > 1 && !genre_list.includes(genre)){
         genre_list.push(genre);
         createTag1();
      }
      e.target.value = "";
   }
}
function addTag2(e){
   if(e.key == "Enter"){
      let keyword = e.target.value.replace(/\s+/g, ' ').replace(',','');
      if(keyword.length > 1 && !keyword_list.includes(keyword)){
         keyword_list.push(keyword);
         createTag2();
      }
      e.target.value = "";
   }
}
function search_value() {
   console.log(genre_list);
   console.log(keyword_list);
   var xhr = new XMLHttpRequest();
   var url = 'http://127.0.0.1:5000/category';
   xhr.open('POST', url, true);
   xhr.setRequestHeader('Content-Type', 'application/json');
   var jsonData = JSON.stringify({ data: genre_list });
   xhr.onreadystatechange = function () {
      if (xhr.readyState === XMLHttpRequest.DONE) {
         console.log(xhr.responseText);
      }
   };
   xhr.send(jsonData);
}
 
 document.getElementById("myform").addEventListener("submit", search_value);
 input1.addEventListener("keyup", addTag1);
 input2.addEventListener("keyup", addTag2);

Python

from flask import Blueprint,request,render_template
Category = Blueprint('category',__name__,static_folder='static',template_folder='templates')
@Category.route('/category')
def category_html():return render_template('category.html')
@Category.route('/category/list',methods=['POST','GET'])
def category_value():
   genre = request.get_json(force=True)
   print(genre)
   ages = request.form["ages"]
   #keyword = 
   types = request.form['types']
   print(ages,types)
   return render_template('list.html',text2=ages,text4=types)

问题原因与解决办法

核心问题

  1. 请求地址不匹配:修改后的JS中XHR请求的是/category,但Python处理数据的路由是/category/list,且该路由同时尝试处理表单数据和JSON数据,两种格式无法共存(request.form和request.get_json不能同时获取有效数据)。
  2. 表单提交与XHR冲突:原有代码既触发表单默认提交,又发送XHR请求,逻辑混乱导致数据传递失败。

方案一:隐藏表单字段传递数组(低改动)

无需使用XHR,在表单中添加隐藏字段,提交前将数组转为逗号分隔的字符串存入字段:

  • HTML新增隐藏字段:在<form>内添加
<input type="hidden" name="genre_list" id="genre_list">
<input type="hidden" name="keyword_list" id="keyword_list">
  • 修改JS的search_value函数:
function search_value() {
  console.log(genre_list);
  console.log(keyword_list);
  // 将数组转为逗号分隔字符串存入隐藏字段
  document.getElementById("genre_list").value = genre_list.join(",");
  document.getElementById("keyword_list").value = keyword_list.join(",");
  document.getElementById("myform").submit();
}
  • 修改Python代码:
@Category.route('/category/list',methods=['POST','GET'])
def category_value():
    # 将字符串转回数组,处理空值情况
    genre_list = request.form.get("genre_list", "").split(",")
    genre_list = genre_list if genre_list != [""] else []
    keyword_list = request.form.get("keyword_list", "").split(",")
    keyword_list = keyword_list if keyword_list != [""] else []
    
    ages = request.form.get("ages", "")
    types = request.form.get("types", "")
    
    print(genre_list, keyword_list, ages, types)
    return render_template('list.html',text2=ages,text4=types, genres=genre_list, keywords=keyword_list)

方案二:纯AJAX请求(无页面跳转)

如果不需要页面跳转,用XHR发送所有数据(包括ages、types):

  • 修改JS的search_value函数:
function search_value(e) {
  // 阻止表单默认提交行为
  e.preventDefault();
  console.log(genre_list);
  console.log(keyword_list);
  
  // 收集所有表单数据
  const ages = document.querySelector("input[name='ages']").value;
  const types = document.querySelector("input[name='types']").value;
  
  var xhr = new XMLHttpRequest();
  var url = '/category/list'; // 使用相对路径避免跨域问题
  xhr.open('POST', url, true);
  xhr.setRequestHeader('Content-Type', 'application/json');
  var jsonData = JSON.stringify({ 
      genres: genre_list,
      keywords: keyword_list,
      ages: ages,
      types: types
  });
  
  xhr.onreadystatechange = function () {
      if (xhr.readyState === XMLHttpRequest.DONE) {
          console.log(xhr.responseText);
          // 可根据需求处理返回结果,比如跳转页面:
          // window.location.href = '/category/list';
      }
  };
  xhr.send(jsonData);
}
// 监听表单提交事件
document.getElementById("myform").addEventListener("submit", search_value);
  • 修改Python代码:
@Category.route('/category/list',methods=['POST','GET'])
def category_value():
    if request.method == 'POST':
        data = request.get_json()
        genre_list = data.get("genres", [])
        keyword_list = data.get("keywords", [])
        ages = data.get("ages", "")
        types = data.get("types", "")
        
        print(genre_list, keyword_list, ages, types)
        return render_template('list.html',text2=ages,text4=types, genres=genre_list, keywords=keyword_list)
    else:
        return render_template('list.html')

额外注意事项

  • 使用相对路径而非绝对路径,避免部署时的跨域或端口变化问题。
  • 使用AJAX时必须阻止表单默认提交行为,否则页面跳转会中断AJAX请求。
  • 处理空值情况,避免空数组转为[""]这类无效数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 15:42:03