前后端数据交互方式总结

本文给出的例子均以flask和python为基础,本人也还处于学习阶段,可能会有错误或者不全的地方,请见谅。

一、前端向后端发送数据

1.1 form表单

前端代码如下:

<form class="form-box" id="loginForm" name="frmlogin" action="/"  method="post" >
 <div class="choose clearfix">
    <span>选择身份</span>
    <div class="choose-one">
      <input type="radio" value="xs" name="type" checked="">
      <lable>学生</lable>
    </div>
    <div class="choose-one">
      <input type="radio" value="js" name="type">
      <lable>教师</lable>
    </div>
 </div>
 <div class="name">
    <div class="form-input input-name">
      <input name="username" id="username" type="text">
    </div>
    <div class="form-input input-code">
      <input name="password" id="password" type="password">
    </div>
 </div>

 <div class="btns clearfix">
    <button id="submit_id" type="submit">登  录</button>      
 </div>
</form>

这是一个登录表单,需要从前端传到后端的主要有两个数据:用户名和密码。虽然代码中有身份的选择,但是为了方便起见,忽略掉身份信息,只查看用户名和密码的数据传递。

后端代码如下:

@student.route("/student", methods=["POST","GET"])
def get_view():
    id = request.form.get('username')
    password = request.form.get('password')
    stu = Student.query.get(id)
    if not stu:
        return render_template('login_new.html', error="用户名或密码错误")
    student_id = id
    student_name = stu.name
    if stu != 'None' and stu.password == password:
        return render_template("demo.html", name=student_name, id=student_id)
    else:
        return render_template('login_new.html', error="用户名或密码错误")

在这里我以学生身份进行了一个简单示范,可能有人注意到,前端表单代码中给出的==action==的值为"/"而后端接收的路由为"/student",这是因为我在前端对身份选择进行了一个判断来改变表单的==action==值。
可以看到flask后端是通过request.form.get()来取得表单里面的值,request是flask库中的一个模块。
需要注意的是,get方法是通过前端input标签里的==name==属性得到的,不是==id==,再次强调是==name==,不是==id==。

身份判断代码:

<script type="text/javascript">
    function changeUrl(){
    var val=document.getElementsByName("type");
    if(val[0].checked){
    document.getElementById('loginForm').action='student';
    }
    if(val[1].checked){
    document.getElementById('loginForm').action='teacher';
    }
}
</script>

1.2 axios数据交互

前端代码如下:

<div class="bl-content" id="test">
    <h2 style="color: #0e0e0e">尝试一下</h2>
    <div class="col-3 input-effect" style="width: 40%">
      <input  type="text" placeholder="第一句" v-model="sentence1">
      <span class="focus-border">
         <i></i>
      </span>
    </div>
    <div class="col-3 input-effect" style="width: 40%">
      <input  type="text" placeholder="第二句" v-model="sentence2">
      <span class="focus-border">
          <i></i>
      </span>
    </div>
    <button class="btn-1" @click="compute_sentence()">计算</button>
</div>

从代码可以看出前端有两个文本输入框,要求用户输入两个句子,然后将这两个句子传到后端计算这两个句子的文本相似度。按钮组件也绑定了vue中的相关点击事件。通过v-model直接将输入文本框的值与vue的data属性里面的值关联起来,实现数据的双向绑定。

vue中methods代码如下:

compute_sentence:function(){
    var obj=this;
    if (obj.sentence1=="" || obj.sentence2 == "") {
        swal({
            title: "输入错误!",
            text: "",
            icon: "error",
            button: "确认"});
                     } 
    else {
        axios.get('/compute_test?sentence1='+obj.sentence1+'&sentence2='+obj.sentence2).then(
            function(response){
                var data=response.data;
                obj.semantic_matching_val=data["semantic_matching_val"];
                obj.text_match_val = data["text_match_val"];
                obj.answer = data["answer"];
                obj.total_score = data["total_score"] 
})}}

代码中将==this==的值赋给obj,使得obj可以访问vue中的data里面的参数。通过axios.get设置好路由和参数,将数据传递给后端。

后端代码如下:

@search.route('/compute_test', methods=["POST", "GET"])
def compute_test():
    sentence1 = request.args["sentence1"]
    sentence2 = request.args["sentence2"]
    text_match_val = text_match_cal2.cal_text_match_for_one(sentence1, sentence2)
    semantic_matching_val = semantic_matching_cal.cal_text_match(sentence1, sentence2)

    rate = float(semantic_matching_val) * 0.25 + 0.75

    total_score = rate * text_match_val

    if total_score >= 0.8:
        answer = "文本相似度较高"
    if 0.8 > total_score >= 0.6:
        answer = "文本相似度一般"
    if total_score < 0.6:
        answer = "文本相似度较低"
    result = {
        "text_match_val": text_match_val,
        "semantic_matching_val": semantic_matching_val,
        "answer": answer,
        "total_score": total_score
    }
    return jsonify(result)

后端通过request.args取得跟随路由传递过来的参数,该方法同样适用于a标签的==href==属性的情况。
中间的代码是关于文本相似度的计算,可以忽略掉,但是为了代码的完整性,我还是贴出来了。
关于文本相似度的计算,最终得到四个相关结果,需要将这四个结果传到前端,首先要将这四个值保存为字典类型,通过jsonify将这个字典转换成json格式,然后return即可。
在上面的vue代码中,通过response.data得到这个json格式的数据,然后格局键值对取得相应数据即可。

二、后端向前端发送数据

flask中后端主动向前端传递数据主要是依靠jinja2的模板引擎,而这也是flask自带的。

2.1简单的信息传递

后端代码如下:

@student.route("/student", methods=["POST","GET"])
def get_view():
    id = request.form.get('username')
    password = request.form.get('password')
    stu = Student.query.get(id)
    if not stu:
        return render_template('login_new.html', error="用户名或密码错误")
    student_id = id
    student_name = stu.name
    if stu != 'None' and stu.password == password:
        return render_template("demo.html", name=student_name, id=student_id)
    else:
        return render_template('login_new.html', error="用户名或密码错误")

还是以之前的登录为例,当用户名或密码错误时,需要在前端显示错误信息,这时函数的返回值==render_template==的参数中多了一项==error==.

前端代码如下:

<p style="color:red">{{error}}</p>

而前端可以通过jinja2的模板语法{{}}取得error参数对应的文本信息。

2.2 javascript接收后端的值

后端代码如下:

@manager.route('/', methods=['POST', 'GET'])
def get_view():
    global type_num, types
    stus = GoodsList.query.group_by(GoodsList.type).all()
    type_num = len(stus)
    for i in range(0, len(stus)):
        types.append(stus[i].type)
    name_list = []  # 统计历史数据
    stus2 = NumberList.query.all()
    history_number = {}
    for i in range(0, len(stus2)):
        number = [stus2[i].day1, stus2[i].day2, stus2[i].day3, stus2[i].day4, stus2[i].day5, stus2[i].day6,
                  stus2[i].day7]
        history_number[stus2[i].name] = number
        name_list.append(stus2[i].name)
    date_list = get_week()
    info = {
        'history_number': history_number,
        'date_list': date_list
    }
    return render_template('index.html', name=name_list, history_number_json=json.dumps(info))

这里给出的是仓库进出货管理系统一个例子,首页需要展示在库商品的相关数据,中间的代码时访问数据库得到商品的种类,近一周进出库的数量等信息。将其这些信息封装成字典形式,render_template函数中设置相应的参数,json.dumps将字典数据转换成json数据。

前端代码如下:

<script>
data ={{history_number_json|safe}}
var date_list = data['date_list']
var number_list = data['history_number']
<\script>

这里的语法涉及到jinja2的过滤器,将history_number_json的值赋给data,然后分别取出相应的值。

2.3 后端数据在前端展示

还是上面的那个例子,在传送给前端的值中除了history_number_json外还有name,并且name的值并非json格式,而是列表格式,存放的是各商品的名称。
前端代码如下:

{%for i in name%}
    <div class="chart">
      <div class="row">
        <div class="col-lg-6 pr-lg-2 chart-grid">
          <div class="card text-center card_border">
            <div class="card-header chart-grid__header">
              {{i}}柱状图
            </div>
            <div class="card-body">
              <!-- bar chart -->
              <div id="container">
                <canvas id="barchart{{loop.index}}"></canvas>
              </div>
              <!-- //bar chart -->
            </div>
            <div class="card-footer text-muted chart-grid__footer">
              昨日更新
            </div>
          </div>
        </div>
        <div class="col-lg-6 pl-lg-2 chart-grid">
          <div class="card text-center card_border">
            <div class="card-header chart-grid__header">
              {{i}}曲线图
            </div>
            <div class="card-body">
              <!-- line chart -->
              <div id="container">
                <canvas id="linechart{{loop.index}}"></canvas>
              </div>
              <!-- //line chart -->
            </div>
            <div class="card-footer text-muted chart-grid__footer">
              昨日更新
            </div>
          </div>
        </div>
      </div>
    </div>
    <!-- //charts -->
     {%endfor%}

jinja2模板提供了循环,判断语法,这里给出了循环语法的使用。这只是对单一列表的遍历,还可以对字典或者多列表的遍历语法。其中loop.index循环计数内置变量,loop.index0是从0开始,loop.index是从1开始。
关于jinja2的更深层次的使用建议去看看官方文档。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇