赞
踩
帖子解决两个问题:
第一、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开头(必须这样否则请求不成功)
后台先配置下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)
表示启成功如下图:
前端发送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('请求超时') } })
请求成功,并返回数据;
下面是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()
注意主函数中需要用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)
}
这样就可以实时接收后端传递过来的的数据了:运行结果如下:
在解决第二个问题
前端开发好的项目打包部署到服务器,服务器的环境用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("请求超时"); } });
其中 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("请求超时"); } });
这样部署到wamp时ajax回去请求完整的url。
flask还需要修改。否则会提示跨域问题。修改如下
增加如下代码,启动后即可。
from flask_cors import *
app = Flask(__name__)
# r'/*' 是通配符,让本服务器所有的URL 都允许跨域请求
CORS(app, resources=r'/*')
完整代码如下:
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()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。