本文介紹如何在Flask項(xiàng)目中集成富文本編輯器UEditor,并實(shí)現(xiàn)文件上傳、圖片上傳、視頻上傳及涂鴉功能。
UEditor是由百度「FEX前端研發(fā)團(tuán)隊(duì)」開發(fā)的所見即所得富文本web編輯器,具有輕量,可定制,注重用戶體驗(yàn)等特點(diǎn),開源基于MIT協(xié)議,允許自由使用和修改代碼。
由于1.4.2版本之后的版本與之前版本存在較大的差異,本文以1.4.3版本為藍(lán)本。
具體文檔參見:http://fex-team.github.io/ueditor/
下載UEditor:
訪問UEditor首頁(yè),下載1.4.3 PHP UTF-8版本的UEditor,并解壓到Flask應(yīng)用程序的static
目錄。解壓之后的目錄結(jié)構(gòu)是這樣的:
| 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
+
表示目錄。
在項(xiàng)目中加入U(xiǎn)Editor:
我們?cè)贔lask應(yīng)用程序的templates
目錄新建一個(gè)index.html
文件(可根據(jù)實(shí)際情況選擇文件名,或者把代碼加入需要使用UEditor的文件):
在head標(biāo)簽加入下面幾行:
<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><!--建議手動(dòng)加在語(yǔ)言,避免在ie下有時(shí)因?yàn)榧虞d語(yǔ)言失敗導(dǎo)致編輯器加載失敗--><!--這里加載的語(yǔ)言文件會(huì)覆蓋你在配置項(xiàng)目里添加的語(yǔ)言類型,比如你在配置項(xiàng)目里配置的是英文,這里加載的中文,那最后就是中文--><script type="text/javascript" charset="utf-8" src="{{ url_for('static', filename='ueditor/lang/zh-cn/zh-cn.js') }}"></script>
在body標(biāo)簽加入:
<script id="editor" type="text/plain"></script><script type="text/javascript"> //實(shí)例化編輯器 //建議使用工廠方法getEditor創(chuàng)建和引用編輯器實(shí)例,如果在某個(gè)閉包下引用該編輯器,直接調(diào)用UE.getEditor('editor')就能拿到相關(guān)的實(shí)例 var ue = UE.getEditor('editor', { serverUrl: "/upload/" });</script>
請(qǐng)求路徑配置:
UEditor 1.4.2+ 起,推薦使用統(tǒng)一的請(qǐng)求路徑,在部署好前端代碼后,需要修改 ueditor.config.js
里的 serverUrl
參數(shù)(或者初始化時(shí)指定,見上面的代碼),改成 '/upload/'
。
UEditor初始化時(shí),會(huì)向后端請(qǐng)求配置文件,后端收到請(qǐng)求后返回JSON格式的配置文件。具體實(shí)現(xiàn)參照后面的代碼。
詳細(xì)配置內(nèi)容參見文檔。
創(chuàng)建Flask應(yīng)用程序(app.py
):
# -*- coding: utf-8 -*-# filename: app.pyfrom flask import Flask, render_templateapp = Flask(__name__)@app.route('/')def index(): return render_template('index.html')@app.route('/upload/', methods=['GET', 'POST'])def upload(): passif __name__ == '__main__': app.run(debug=True)
應(yīng)用程序運(yùn)行之后,我們?cè)L問 http://localhost:5000/
就可以看到UEditor編輯器了,上圖:
與后臺(tái)通信的功能列表:
統(tǒng)一請(qǐng)求格式說(shuō)明:
/upload/
處理前端的請(qǐng)求/upload/
通過GET上的action
參數(shù),判斷是什么類型的請(qǐng)求cb({"key": "value"})
詳細(xì)說(shuō)明:http://fex-team.github.io/ueditor/#dev-request_specification
由于接口升級(jí),編輯器初始化時(shí),首先會(huì)向后端請(qǐng)求配置信息,后端收到請(qǐng)求后,返
回相應(yīng)的配置信息即可。
請(qǐng)求參數(shù):
GET {"action": "config"}POST "upfile": File Data
返回格式:
// 需要支持callback參數(shù),返回jsonp格式{ "imageUrl": "http://localhost/ueditor/php/controller.php?action=uploadimage", "imagePath": "/ueditor/php/", "imageFieldName": "upfile", "imageMaxSize": 2048, "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"]}
主要功能代碼:
@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': # 初始化時(shí),返回配置文件給客戶端 result = CONFIG return json.dumps(result)
圖片上傳包括:本地圖片上傳、拖拽圖片上傳、粘貼板圖片上傳。
這些功能實(shí)現(xiàn)的方法是一樣的,所以放到一起來(lái)講。上傳的文件可用request.files['upfile']
獲取。
請(qǐng)求參數(shù):
GET {"action": "uploadimage"}POST "upfile": File Data
action說(shuō)明:
返回格式:
{ "state": "SUCCESS", "url": "upload/demo.jpg", "title": "demo.jpg", "original": "demo.jpg"}
主要功能代碼:
@app.route('/upload/', methods=['GET', 'POST'])def upload(): result = {} action = request.args.get('action') if action in ('uploadimage', 'uploadvideo', 'uploadfile'): upfile = request.files['upfile'] # 這個(gè)表單名稱以配置文件為準(zhǔn) # upfile 為 FileStorage 對(duì)象 # 這里保存文件并返回相應(yīng)的URL upfile.save(filename_to_save) result = { "state": "SUCCESS", "url": "upload/demo.jpg", "title": "demo.jpg", "original": "demo.jpg" } return json.dumps(result)
涂鴉功能上傳經(jīng)過BASE64編碼的圖片(一般為PNG格式),可用request.form['upfile']
獲取,后端收到之后需要先解碼,再保存。
請(qǐng)求參數(shù):
GET {"action": "uploadscrawl"}POST "content": Base64 Data
返回格式:
{ "state": "SUCCESS", "url": "upload/demo.jpg", "title": "demo.jpg", "original": "demo.jpg"}
主要功能代碼:
@app.route('/upload/', methods=['GET', 'POST'])def upload(): result = {} action = request.args.get('action') if action in ('uploadscrawl'): base64data = request.form['upfile'] # 這個(gè)表單名稱以配置文件為準(zhǔn) img = base64.b64decode(base64data) # 這里保存文件并返回相應(yīng)的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)
遠(yuǎn)程抓圖主要是把站外的圖片保存到本地或者指定的圖片服務(wù)器。
當(dāng)復(fù)制粘貼其他網(wǎng)站的網(wǎng)頁(yè)的圖片時(shí),會(huì)觸發(fā)遠(yuǎn)程抓圖功能。
遠(yuǎn)程圖片列表可通過request.form.getlist('source[]')
獲取。這里暫時(shí)不清楚是
什么原因,為什么request.form.getlist('source')
為空。
核心思路:遍歷遠(yuǎn)程圖片列表,通過urllib把圖片下載并保存,下載完成之后按照格
式返回結(jié)果。
請(qǐng)求參數(shù):
GET { "action": "catchimage", "source": [ "http://a.com/1.jpg", "http://a.com/2.jpg" ]}
返回格式:
// 需要支持callback參數(shù),返回jsonp格式// list項(xiàng)的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
實(shí)現(xiàn)了圖片上傳、附件上傳、視頻上傳、涂鴉、遠(yuǎn)程抓圖等功能。
聯(lián)系客服