VUE+FLASK前后端分离(回答面试题之“你来说说restful前后端代码怎么写”)

VUE+FLASK前后端分离(回答面试题之“你来说说restful前后端代码怎么写”)

动机

前段时间出去面试,遇到了好几次对方面试官问这样的问题,”restful风格的代码,前后端怎么写?”,“从浏览器前端到后台经过了哪些?说的越详细越好。”这样的问题,我听到的第一时刻是懵逼的,啥情况?我要从vue的双向数据绑定开始说吗?axios的用法要说吗?falsk的restful是如何用‘’/api/‘’对应前台的url的吗?还是去说spring框架的mvc? 产生这样的疑惑,主要原因是,我不明白面试官为什么要问这样的问题?实现起来很简单,但是说起来又太宽泛,不知道说的是不是面试官想要的答案,容易偏题。 在我回头仔细想想了之后,决定以后再遇到这样的问题,就使用vue+falsk做例子来讲解这个。

回答策略

按照下面的几步,顺序回答

  1. 以vue+flask 前后端分离为基础,以用户登录,输入用户名密码为场景。
  2. vue前端框架通过v-model获得输入框输入的用户名以及密码。通过引入axios向后台发起http请求,axios是一个http库,可以在nodejs中使用,使用方式有一点类似ajax。通过axios.post(“/api”,{param:”param”})的方式向后台发起http请求。
  3. 后台的flask运行起来之后,通过装饰圈route.配置路由@app.route(‘/api’,methods=[“GET”,”POST”]) 来对应前台http请求的url,如果没有对应的url会返回404。如果找到对应的路由,则会进入相应的方法,进行运算,完成运算之后,可以用json.dumps把数据作为json返回。
  4. axios前台的response收到后,通过response.data获得返回的json,然后可以把相应的值进行变更

代码实现

  • 前端vue关键代码之 index.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <title>vueapp01</title>
  <script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
</head>
<style>
  .class1{
    background: #444;
    color: #eee;
  }
</style>
<body>
  <div id="app3"></div>
</body>
</html>
  • 前端vue关键代码之main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import Lzw from './components/Lzw'
import router from './router'
import axios from 'axios'
import BootstrapVue from 'bootstrap-vue'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
Vue.use(BootstrapVue)
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
  el: '#app3',
  router,
  axios,
  components: { Lzw },
  template: '<Lzw/>'
})
  • 前端vue关键代码之Lzw.vue

使用axios需要先安装axios库和HTTP2库

npm install –save axios
npm install –save http2

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <div id="example-3">
      <input type="checkbox" id="jack" value="白金会员" v-model="checkedNames">
      <label for="jack">白金会员</label>
      <input type="checkbox" id="john" value="黄金会员" v-model="checkedNames">
      <label for="john">黄金会员</label>
      <input type="checkbox" id="mike" value="王者会员" v-model="checkedNames">
      <label for="mike">王者会员</label>
      <br>
      <strong>选择会员种类: {{ checkedNames }}</strong>
    </div>
    <div id="app2">
      <input v-model="username" placeholder="用户名">
      <p>用户名是: {{ username }}</p>
      <input type="password" v-model="password" placeholder="密码">
      <p>密码是: {{ password }}</p>
      <button class="btn btn-large btn-primary" v-on:click="login">向后台发送post请求,传递用户名和密码,变更用户ID</button>
      <p>用户ID是: {{ id }}</p>
      <button class="btn btn-large btn-primary" v-on:click="getmsg">向后台发送get请求,把用户ID变成0</button>
    </div>
  </div>
</template>
<script>
import axios from "axios";
export default {
  name: "hello",
  data() {
    return {
      msg: "欢迎来到测试开发笔记!",
      checkedNames: [],
      username: "",
      password: "",
      id: "密码反转+用户名反转"
    };
  },
  methods: {
    login() {
      var that = this;
      // 对应 Python 提供的接口,这里的地址填写下面服务器运行的地址,本地则为127.0.0.1,外网则为 your_ip_address
      const path = "http://127.0.0.1:5000/getMsg";
      axios
        .post(path, { username: this.username, password: this.password })
        .then(response => {
          this.id = response.data.userid;
        });
    },
    getmsg() {
      var that = this;
      // 对应 Python 提供的接口,这里的地址填写下面服务器运行的地址,本地则为127.0.0.1,外网则为 your_ip_address
      const path = "http://127.0.0.1:5000/getMsg";
      // 务必使用箭头函数的方法,这样this.id能直接对上,不然会报错提示id没找到
      axios
        .get(path, { username: this.username, password: this.password })
        .then(response => {
          this.id = response.data.userid;
        });
    }
  }
};
</script>
  • 后端flask关键代码main.py

flask要避免跨域问题。需要安装Flask库和Falsk-Cors库

from flask import Flask, url_for,request
from flask_cors import *
import json
app = Flask(__name__)
# 这句话解决跨域问题
CORS(app, supports_credentials=True)
@app.route('/getMsg',methods=["GET","POST"])
def getMsg():
    if request.method == 'POST':
        username = request.json['username']
        password= request.json['password']
        # 假定用户id是密码反转+用户名反转得出来的
        datat = {
            "userid": username[::-1]+password[::-1],
        }
        return json.dumps(datat)
    elif request.method == 'GET':
        datat = {
            "userid": 0,
        }
        return json.dumps(datat)
if __name__ == '__main__':
    app.debug = True
    app.run()

苏ICP备18047533号-1