当前位置:   article > 正文

vue-cli项目前后端分离数据交互之ajax和后台python通信flask,web服务器 wampserver和flask兼容!!_vue使用ajax调用python接口

vue使用ajax调用python接口

帖子解决两个问题:
第一、ajax发出请求后端用flask轻量化部署,包括websocket通信
第二、web服务器部署集成环境wamrserver和flask冲突(具体表现在:ajax中的请求会默认wamp不会指向flask)

先解决第一个问题:

用vue-cli 创建项目后配置下 项目的配置文件,config/index.js 找到proxyTable,配置如下:

亲测有效的方法
proxyTable: {
        '/api/*':{ //这里面的  '/api/*' 才好用, 其他的形式如:'/api'不失败的
        target:'http://xxxx.com;8011',
        changeOrigin: true,//跨域(很重要,前后端分离时所在服务器ip不同会涉及到跨域的问题)
        pathRewrite: {
          '^/api': '/api'  // 这里的/api 会替代http://xxxx.com, 具体前端请求例子往下看
        }
      }
      //这里设置的请求用/api替代,所以后台flask中的请求地址也应该是/api开头(必须这样否则请求不成功)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

后台先配置下flask,如下代码,保存到.py文件后在cmd中python run.py运行,会启动flask服务

其中@app.route(’/api/aa/hello_world’,methods=[‘GET’,‘POST’]) 和@app.route(’/api/sendAjax2’, methods=[‘POST’])中带请求地址必须都以/api开头同config/index.js 里的proxyTable设置中保持一致,

待请求中的最后面hello_world和sendAjax2是后台对应的方法,待请求结尾必须以方法名结尾,表示调用该方法。

from flask import Flask
from flask import request
import json
app = Flask(__name__) 
@app.route('/api/aa/hello_world',methods=['GET','POST'])//待请求的地址以/api开头
def hello_world(): 
 data =  request.form.get("data")//接收前端传过来的参数
 print(data)
 return (data)
 
@app.route('/api/sendAjax2', methods=['POST'])/待请求的地址以/api开头
def sendAjax2():
    return "46575"
#接收前端上传的真实设备xlsx文件
@app.route('/api/upload_xlsx', methods=['POST'])
def upload_xlsx(): 
    f = request.files['file']
    filename = f.filename
    upload_file = request.files['file']
    upload_file.save('{}/{}'.format(os.getcwd(), filename))
    os.rename('{}/{}'.format(os.getcwd(), filename), '{}/{}'.format(os.getcwd(), 'Device.xlsx'))#重命名
    return '{}/{}'.format(os.getcwd(), 'Device.xlsx')

#接收前端上传的虚拟设备zip压缩包
@app.route('/api/upload_zip', methods=['POST'])
def upload_zip(): 
    f = request.files['file']
    filename = (f.filename)
    print(filename)
    print(filename.encode('gbk'))
    upload_file = request.files['file']
    upload_file.save(r'{}/{}'.format(os.getcwd(), filename))
    os.rename(r'{}/{}'.format(os.getcwd(), filename), r'{}/{}'.format(os.getcwd(), 'SimulateDevice.zip'))#重命名
    return r'{}/{}'.format(os.getcwd(), 'SimulateDevice.zip')
if __name__ == '__main__': 
    app.run(host='0.0.0.0', port=8011, debug=True)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

表示启成功如下图:
在这里插入图片描述
前端发送ajax 请求;

data=111’
 $.ajax({
             // cache: true,
             // async: false, // 注意:这里设置为flase,即同步操作,因为我们不需要异步操作,只是传参而已,当然,你也可以设置成异步。
             contentType: 'application/x-www-form-urlencoded; charset=utf-8', // 这个要写对,和你的页面照应,你的页面是gb2312就填gb2312,我这里是utf8,否则中文传参会出错。
             url: '/api/aa/hello_world', // 这里就是上面配置的用 /api代替http://xxxx.com:8011
             type: 'POST', // 
             traditional: true, // 序列化数据
             data: {
               data: data
             },
             success: function (data) {
               data = JSON.parse(data)
               console.log(data)
               alert(data)
             },
             error: function () { // 出错处理,一般加上,但其实传参没什么出错。
               alert('请求超时')
             }
           })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

请求成功,并返回数据;
在这里插入图片描述

下面是websocket 实时通讯,后端不断地向前端发送状态,前端接收并做展示等操作:
后端python 会用到websocket组件,先安装 pip install gevent-websocket

#coding=utf-8
from flask import Flask, request,render_template
from geventwebsocket.websocket import WebSocket
from gevent.pywsgi import WSGIServer
from geventwebsocket.handler import WebSocketHandler
import json
import sys
import os
user_socket_dict = {}
app = Flask(__name__)
reload(sys)
sys.setdefaultencoding('utf8')
@app.route('/')
def index():
    return render_template('index.html')
#接收前端上传的真实设备xlsx文件
@app.route('/api/upload_xlsx', methods=['POST'])
def upload_xlsx(): 
    f = request.files['file']
    filename = f.filename
    upload_file = request.files['file']
    upload_file.save('{}/aa/{}'.format(os.getcwd(), filename))
    return '{}/{}'.format(os.getcwd(), 'Device.xlsx')

#接收前端上传的虚拟设备zip压缩包
@app.route('/api/upload_zip', methods=['POST'])
def upload_zip(): 
    f = request.files['file']
    filename = (f.filename)
    print(filename)
    print(filename.encode('gbk'))
    upload_file = request.files['file']
    upload_file.save(r'{}/{}'.format(os.getcwd(), filename))
    os.rename(r'{}/{}'.format(os.getcwd(), filename), r'{}/{}'.format(os.getcwd(), 'SimulateDevice.zip'))#重命名
    return r'{}/{}'.format(os.getcwd(), 'SimulateDevice.zip')
@app.route('/ws')
def ws():
    user_socket = request.environ.get('wsgi.websocket') # type:WebSocket  
    if user_socket:
        while True:// 测试代码用死循环来方便,具体业务需根据情况写逻辑
            user_socket.send('sss')
            print('sss')
                

if __name__ == '__main__':
    http_serv = WSGIServer(('0.0.0.0',8011),app,handler_class=WebSocketHandler)
    http_serv.serve_forever()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

注意主函数中需要用http.serv 这样的写法才可,前端发送一次请求后后端实时主动发送状态
前端请求新建websocket,如下:
前端触发函数中写如下代码发送请求

//WebSocket 接收数据
           var ws = new WebSocket('ws://127.0.0.1:8011/ws');// 服务端ip端口/ws方法名与def ws():需要一致
           ws.onmessage = function (data) {
               console.log(data.data)
           }
  • 1
  • 2
  • 3
  • 4
  • 5

这样就可以实时接收后端传递过来的的数据了:运行结果如下:
在这里插入图片描述
在解决第二个问题
前端开发好的项目打包部署到服务器,服务器的环境用wampserver(apache + mysql + PHP)集成环境一键安装部署比较省事,还有个问题是网站要执行单点登录,我只会php的所以就这么选择了。

因为vue项目时部署在wamp集成环境中所以原来的ajax请求方式会报错提示,服务器没有此路径,所以需要变更下请求url如下:

原来方式:

 $.ajax({
        // cache: true,
        // contentType: 'application/json; charset=utf-8',
        async: false,  
        contentType: "application/x-www-form-urlencoded; charset=utf-8",   
        url: "/api/config/start_run", //
        type: "POST", //
        // traditional: true, // 序列化数据
        data: {
          data: array
        },
        success: function(data) { 
          console.log(data); 
        },
        error: function() { 
          alert("请求超时");
        }
      });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

其中 url: “/api/config/start_run”, 这句话是因为config 中index.js设置了proxyTable.上面有配置,在没有部署到wamp 时可以执行成功,部署后会提示无此路径,所以ajax请求就要变成下面的:
需要完整的url路径。

$.ajax({
        // cache: true,
        // contentType: 'application/json; charset=utf-8',
        async: false,  
        contentType: "application/x-www-form-urlencoded; charset=utf-8",  
        url: "http://10.10.10.10:8011/api/config/start_run", //
        type: "POST", //
        traditional: true, // 序列化数据
        data: {
          data: array
        },
        success: function(data) {
          data = JSON.parse(data);
          console.log(data); 
        },
        error: function() { 
          alert("请求超时");
        }
      });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

这样部署到wamp时ajax回去请求完整的url。

flask还需要修改。否则会提示跨域问题。修改如下
增加如下代码,启动后即可。

from flask_cors import *

app = Flask(__name__)
# r'/*' 是通配符,让本服务器所有的URL 都允许跨域请求 
CORS(app, resources=r'/*')
  • 1
  • 2
  • 3
  • 4
  • 5

完整代码如下:

from flask import Flask, request
from geventwebsocket.websocket import WebSocket
from gevent.pywsgi import WSGIServer
from geventwebsocket.handler import WebSocketHandler 

from flask_cors import *

app = Flask(__name__)
CORS(app, resources=r'/*')


WEBSOCKET_DICT = {}
@app.route('/api/ws')
def ws():
    user_socket = request.environ.get('wsgi.websocket')
    if user_socket:
        while True:
            user_socket.send('sss')
            print('sss')


@app.route('/api/config/start_run', methods=['GET', 'POST'])
def start_run():
    # 接收业务配置参数
    data = request.form.get("data")
    print(data)
    return 'sssssss'


if __name__ == '__main__':
    # app.run(host='0.0.0.0', port=8011, debug=True)
    http_serv = WSGIServer(('0.0.0.0', 8011), app,handler_class=WebSocketHandler)
    http_serv.serve_forever()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/66595?site
推荐阅读
相关标签
  

闽ICP备14008679号