本文介绍如何在Flask项目中集成富文本编辑器UEditor,并实现文件上传、图片上传、视频上传及涂鸦功能。javascript
UEditor是由百度「FEX前端研发团队」开发的所见即所得富文本web编辑器,具备轻量,可定制,注重用户体验等特色,开源基于MIT协议,容许自由使用和修改代码。php
因为1.4.2版本以后的版本与以前版本存在较大的差别,本文以1.4.3版本为蓝本。html
具体文档参见:http://fex-team.github.io/ueditor/前端
下载UEditor:java
访问UEditor首页,下载1.4.3 PHP UTF-8版本的UEditor,并解压到Flask应用程序的static
目录。解压以后的目录结构是这样的:python
| static/ | | ueditor/ | | |+dialogs/ | | |+lang/ | | |+php/ | | |+themes/ | | |+third-party/ | | |-config.json | | |-index.html | | |-ueditor.all.js | | |-ueditor.all.min.js | | |-ueditor.config.js | | |-ueditor.parse.js | | |-ueditor.parse.min.js
+
表示目录。git
在项目中加入UEditor:github
咱们在Flask应用程序的templates
目录新建一个index.html
文件(可根据实际状况选择文件名,或者把代码加入须要使用UEditor的文件):web
在head标签加入下面几行:json
html<script type="text/javascript" charset="utf-8" src="{{ url_for('static', filename='ueditor/ueditor.config.js') }}"></script> <script type="text/javascript" charset="utf-8" src="{{ url_for('static', filename='ueditor/ueditor.all.min.js') }}"> </script> <!--建议手动加在语言,避免在ie下有时由于加载语言失败致使编辑器加载失败--> <!--这里加载的语言文件会覆盖你在配置项目里添加的语言类型,好比你在配置项目里配置的是英文,这里加载的中文,那最后就是中文--> <script type="text/javascript" charset="utf-8" src="{{ url_for('static', filename='ueditor/lang/zh-cn/zh-cn.js') }}"></script>
在body标签加入:
html<script id="editor" type="text/plain"></script> <script type="text/javascript"> //实例化编辑器 //建议使用工厂方法getEditor建立和引用编辑器实例,若是在某个闭包下引用该编辑器,直接调用UE.getEditor('editor')就能拿到相关的实例 var ue = UE.getEditor('editor', { serverUrl: "/upload/" }); </script>
请求路径配置:
UEditor 1.4.2+ 起,推荐使用统一的请求路径,在部署好前端代码后,须要修改 ueditor.config.js
里的 serverUrl
参数(或者初始化时指定,见上面的代码),改为 '/upload/'
。
UEditor初始化时,会向后端请求配置文件,后端收到请求后返回JSON格式的配置文件。具体实现参照后面的代码。
详细配置内容参见文档。
建立Flask应用程序(app.py
):
python# -*- coding: utf-8 -*- # filename: app.py from flask import Flask, render_template app = Flask(__name__) @app.route('/') def index(): return render_template('index.html') @app.route('/upload/', methods=['GET', 'POST']) def upload(): pass if __name__ == '__main__': app.run(debug=True)
应用程序运行以后,咱们访问 http://localhost:5000/
就能够看到UEditor编辑器了,上图:
与后台通讯的功能列表:
统一请求格式说明:
/upload/
处理前端的请求/upload/
经过GET上的action
参数,判断是什么类型的请求cb({"key": "value"})
详细说明:http://fex-team.github.io/ueditor/#dev-request_specification
因为接口升级,编辑器初始化时,首先会向后端请求配置信息,后端收到请求后,返
回相应的配置信息便可。
请求参数:
GET {"action": "config"} POST "upfile": File Data
返回格式:
// 须要支持callback参数,返回jsonp格式 { "imageUrl": "http://localhost/ueditor/php/controller.php?action=uploadimage", "imagePath": "/ueditor/php/", "imageFieldName": "upfile", "imageMaxSize": 2048, "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"] }
主要功能代码:
python@app.route('/upload/', methods=['GET', 'POST']) def upload(): action = request.args.get('action') # 解析JSON格式的配置文件 # 这里使用PHP版本自带的config.json文件 with open(os.path.join(app.static_folder, 'ueditor', 'php', 'config.json')) as fp: try: # 删除 `/**/` 之间的注释 CONFIG = json.loads(re.sub(r'\/\*.*\*\/', '', fp.read())) except: CONFIG = {} if action == 'config': # 初始化时,返回配置文件给客户端 result = CONFIG return json.dumps(result)
图片上传包括:本地图片上传、拖拽图片上传、粘贴板图片上传。
这些功能实现的方法是同样的,因此放到一块儿来说。上传的文件可用request.files['upfile']
获取。
请求参数:
GET {"action": "uploadimage"} POST "upfile": File Data
action说明:
返回格式:
{ "state": "SUCCESS", "url": "upload/demo.jpg", "title": "demo.jpg", "original": "demo.jpg" }
主要功能代码:
python@app.route('/upload/', methods=['GET', 'POST']) def upload(): result = {} action = request.args.get('action') if action in ('uploadimage', 'uploadvideo', 'uploadfile'): upfile = request.files['upfile'] # 这个表单名称以配置文件为准 # upfile 为 FileStorage 对象 # 这里保存文件并返回相应的URL upfile.save(filename_to_save) result = { "state": "SUCCESS", "url": "upload/demo.jpg", "title": "demo.jpg", "original": "demo.jpg" } return json.dumps(result)
涂鸦功能上传通过BASE64编码的图片(通常为PNG格式),可用request.form['upfile']
获取,后端收到以后须要先解码,再保存。
请求参数:
GET {"action": "uploadscrawl"} POST "content": Base64 Data
返回格式:
{ "state": "SUCCESS", "url": "upload/demo.jpg", "title": "demo.jpg", "original": "demo.jpg" }
主要功能代码:
python@app.route('/upload/', methods=['GET', 'POST']) def upload(): result = {} action = request.args.get('action') if action in ('uploadscrawl'): base64data = request.form['upfile'] # 这个表单名称以配置文件为准 img = base64.b64decode(base64data) # 这里保存文件并返回相应的URL with open(filename_to_save, 'wb') as fp: fp.write(img) result = { "state": "SUCCESS", "url": "upload/demo.jpg", "title": "demo.jpg", "original": "demo.jpg" } return json.dumps(result)
远程抓图主要是把站外的图片保存到本地或者指定的图片服务器。
当复制粘贴其余网站的网页的图片时,会触发远程抓图功能。
远程图片列表可经过request.form.getlist('source[]')
获取。这里暂时不清楚是
什么缘由,为何request.form.getlist('source')
为空。
核心思路:遍历远程图片列表,经过urllib把图片下载并保存,下载完成以后按照格
式返回结果。
请求参数:
GET { "action": "catchimage", "source": [ "http://a.com/1.jpg", "http://a.com/2.jpg" ] }
返回格式:
// 须要支持callback参数,返回jsonp格式 // list项的state属性和最外面的state格式一致 { "state": "SUCCESS", "list": [{ "url": "upload/1.jpg", "source": "http://b.com/2.jpg", "state": "SUCCESS" }, { "url": "upload/2.jpg", "source": "http://b.com/2.jpg", "state": "SUCCESS" }, ] }
Flask UEditor完整DEMO:https://coding.net/u/wtx358/p/flask-ueditor-demo/git
实现了图片上传、附件上传、视频上传、涂鸦、远程抓图等功能。