html 如何将JavaScript数组传递给Python Flask

kg7wmglp  于 12个月前  发布在  Java
关注(0)|答案(2)|浏览(128)

我并不是JavaScript的Maven,但我有一个学校项目,我需要使用python flask来制作一个网站。问题是,当我在html上输入时,我把值放在javascript数组中,然后我需要把它发送到python,在那里我可以处理数据。有人知道怎么做吗?
代码如下: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)


根据我的研究,我尝试过使用xmlhttprequest(),但似乎效果不好
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)

1hdlvixo

1hdlvixo1#

HTTP请求只处理字符串。即使是通过JSON这样常见的规范发送数据,也会在发送方(客户端)格式化字符串,并在接收方(服务器端)解析该字符串。因此,您不会从JS应用向Python应用发送数组,而是发送一个由JS应用格式化并由Python应用解释的字符串。
不同的Web框架有不同的方法来处理“类似数组”的数据。例如,一些API将以?tags[]=a&tags[]=b&tags=c发送的参数解释为数组['a', 'b', 'c']。同样,不同的HTTP请求客户端库使用不同的策略来格式化/序列化请求中发送的数据。
在Flask中,我相信你使用form.getlist('tags[]')方法从提交的表单中提取一个列表。这将要求你的表单输入配置有name=tags[]属性。但是,如果你向服务器发送JSON,你可以按照你喜欢的格式设置它。只要确保在尝试访问属性之前,你正在Flask中将字符串解析为JSON对象。
此外,当你的Flask路由被设置为在/category/list接受POST请求时,看起来你正在向你的/category端点发出POST请求。

mtb9vblg

mtb9vblg2#

要保存你用AJAX工作,可以保存数组的元素与分隔符在一个隐藏的输入。所以你可以发送的形式在通常的方式。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Index</title>
</head>
<body>
    <form method="post">
        <div class="tag-input">
            <ul class="tags"></ul>
            <input type="text" placeholder="Add a tag" />
            <input type="hidden" name="tags" />
        </div>
        <button type="submit">Submit</button>
    </form>

    <script>
        class TagsField {
            constructor(elem) {
                this.elem = elem;
                this.tags = elem.querySelector('.tags');
                this.input = elem.querySelector('input[type="text"]');
                this.hidden = elem.querySelector('input[type="hidden"]');
                this.#init();
            }
            #init() {
                this.#createTagsList(this.hidden.value !== '' ? this.hidden.value.split(';') : []);
                this.input.addEventListener('keydown', (event) => {
                    if (event.key === 'Enter') {
                        event.preventDefault();
                        let tagValue = this.input.value.trim();
                        let tagValues = this.hidden.value !== '' ? this.hidden.value.split(';') : [];
                        if (tagValue && !tagValues.includes(tagValue)) {
                            tagValues.push(tagValue);
                            this.#createTagsList(tagValues); 
                            this.hidden.value = tagValues.join(';');
                        }
                        this.input.value = '';
                    }
                });
            }
            #createTagsList(values) {
                this.tags.innerHTML = values.map(value => {
                    return `<li class="tag"><span class="value">${value}</span><button type="button">&times;</button></li>`;
                }).join('');
                this.tags.querySelectorAll('li.tag button').forEach(elem => {
                    elem.addEventListener('click', event => {
                        let target = event.target;
                        let value = target.parentElement.querySelector('.value').innerText;
                        let values = this.hidden.value.split(';');
                        values.splice(values.indexOf(value), 1);
                        this.hidden.value = values.join(';');
                        target.parentElement.remove();
                    });
                });
            }
        }

        (function() {
            const elems = document.querySelectorAll('.tag-input');
            elems.forEach(elem => new TagsField(elem));
        })();
    </script>

</body>
</html>

字符串
然后,您可以在服务器上再次分离这些元素。

from flask import (
    Flask, 
    render_template,
    request
)

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        tags = request.form.get('tags', [], type=lambda x: x.strip().split(';') if x.strip() else [])
    return render_template('index.html')


所示的示例当然可以改进,但它说明了它是如何工作的。

相关问题