本文介紹如何在Flask項目中集成富文本編輯器xhEditor,並實現圖片上傳、文件上傳、視頻上傳、遠程抓圖等(包括拖拽上傳)功能。javascript
xhEditor是一個基於jQuery開發的簡單迷你而且高效的可視化HTML編輯器,基於網絡訪問而且兼容IE 6.0+, Firefox 3.0+, Opera 9.6+, Chrome 1.0+, Safari 3.22+。html
xhEditor曾經是我比較喜歡的編輯器,也是率先支持拖拽上傳的編輯器之一。xhEditor在當年是優秀的編輯器,功能足夠強大,使用體驗也至關好,拖拽上傳是我最喜歡的功能,只惋惜已經中止開發了。xhEditor最後的穩定版本是1.1.14,至今已超過2年未更新(2013年發佈了開發版本1.2.1),做者已經中止開發和維護了,社區論壇徹底不能打開。java
因爲xhEditor基於jQuery開發,而對於新版本的jQuery,它並不能很好的支持,只有1.4版本的jQuery是支持得最好的。python
雖然已經再也不更新了,但在一些須要富文本編輯器的場合,她仍是能夠徹底勝任的。jquery
本文以1.1.14版本爲例,講述如何在Flask項目中使用xhEditor編輯器,並實現圖片上傳、文件上傳的後端功能。git
首先咱們須要到xhEditor官網下載1.1.14版本的xhEditor編輯器,下載以後解壓到
Flask項目的static/xheditor
目錄。正則表達式
xhEditor提供2種初始化方式:Class初始化和JavaScript初始化。Class初始化只須要給textarea設置值爲xheditor
的class
屬性,它就會自動變成xhEditor編輯器,一個頁面能夠同時同在多個編輯器,並且這個類屬性能夠添加參數。(PS:CKEditor也有這個功能)json
對於這兩種初始化方式,官網有提供設置很方便的設置嚮導,使得配置相對比較簡單。flask
示例代碼:後端
html<head> <script type="text/javascript" charset="utf-8" src="{{ url_for('static', filename='xheditor/jquery/jquery-1.4.4.min.js') }}"></script> <script type="text/javascript" charset="utf-8" src="{{ url_for('static', filename='xheditor/xheditor-1.1.14-zh-cn.min.js') }}"></script> <style>.xheditor {width: 640px; height:320px;}</style> </head> <body> <textarea id="content" name="content" class="xheditor {tools:'mfull'}"></textarea> </body>
如今,咱們就擁有一個xhEditor編輯器了。
xhEditor的上傳功能須要設置幾個參數(以圖片上傳爲例):
upImgUrl
: 圖片文件上傳接收URL,例:/upload/
,可以使用內置變量{editorRoot}
upImgExt
: 圖片上傳前限制本地文件擴展名,默認:jpg,jpeg,gif,png這裏假設上傳文件接收URL爲/upload/
,咱們的編輯器初始化代碼就變成:
html<textarea class="xheditor {tools:'mfull',upImgUrl:'/upload/'}"></textarea>
其餘類型的文件上傳設置類推。
xhEditor支持2種上傳方式:標準HTML4上傳和HTML5上傳。
filedata
HTTP_CONTENT_DISPOSITION
這個服務器變量中返回內容必需是標準的json字符串,結構能夠是以下:{"err":"","msg":"200906030521128703.gif"}
或者{"err":"","msg":{"url":"200906030521128703.jpg","localfile":"test.jpg","id":"1"}}
注:若選擇結構2,則url
變量是必有。
文件上傳處理示例代碼:
pythondef gen_rnd_filename(): filename_prefix = datetime.datetime.now().strftime('%Y%m%d%H%M%S') return '%s%s' % (filename_prefix, str(random.randrange(1000, 10000))) @app.route('/upload/', methods=['GET', 'POST']) def upload(): '''文件上傳函數 本函數未作上傳類型判斷及上傳大小判斷。 ''' result = {"err": "", "msg": {"url": "", "localfile": ""}} if request.method == 'POST' and 'filedata' in request.files: # 傳統上傳模式,IE瀏覽器使用這種模式 fileobj = request.files['filedata'] fname, fext = os.path.splitext(fileobj.filename) rnd_name = '%s%s' % (gen_rnd_filename(), fext) fileobj.save(os.path.join(app.static_folder, 'upload', rnd_name)) result["msg"]["localfile"] = fileobj.filename result["msg"]["url"] = '!%s' % \ url_for('static', filename='%s/%s' % ('upload', rnd_name)) elif 'CONTENT_DISPOSITION' in request.headers: # HTML5上傳模式,FIREFOX等默認使用此模式 pattern = re.compile(r"""\s.*?\s?filename\s*=\s*['|"]?([^\s'"]+).*?""", re.I) _d = request.headers.get('CONTENT_DISPOSITION').encode('utf-8') if urllib.quote(_d).count('%25') > 0: _d = urllib.unquote(_d) filenames = pattern.findall(_d) if len(filenames) == 1: result["msg"]["localfile"] = urllib.unquote(filenames[0]) fname, fext = os.path.splitext(filenames[0]) img = request.data rnd_name = '%s%s' % (gen_rnd_filename(), fext) with open(os.path.join(app.static_folder, 'upload', rnd_name), 'wb') as fp: fp.write(img) result["msg"]["url"] = '!%s' % \ url_for('static', filename='%s/%s' % ('upload', rnd_name)) return json.dumps(result)
通常狀況下,當複製站外的圖片時,咱們但願能夠把圖片保存到本地,遠程抓圖就能夠完成這個事情。
啓用遠程抓圖功能,須要設置2個參數:
localUrlTest
: 非本站域名測試正則表達式remoteImgSaveUrl
: 遠程圖片抓取接收程序URL設置這2個參數以後,咱們的編輯器初始化代碼變成:
html<textarea class="xheditor {tools:'mfull',upImgUrl:'/upload/',localUrlTest:/^https?:\/\/[^\/]*?(localhost:?\d*)\//i,remoteImgSaveUrl:'/uploadremote/'}"></textarea>
這裏表示抓取除localhost
以外其它域名的圖片。
遠程抓圖處理示例代碼:
pythondef gen_rnd_filename(): filename_prefix = datetime.datetime.now().strftime('%Y%m%d%H%M%S') return '%s%s' % (filename_prefix, str(random.randrange(1000, 10000))) @app.route('/uploadremote/', methods=['POST']) def uploadremote(): """ xheditor保存遠程圖片簡單實現 URL用"|"分隔,返回的字符串也是用"|"分隔 返回格式是字符串,不是JSON格式 """ localdomain_re = re.compile(r'https?:\/\/[^\/]*?(localhost:?\d*)\/', re.I) imageTypes = {'gif': '.gif', 'jpeg': '.jpg', 'jpg': '.jpg', 'png': '.png'} urlout = [] result = '' srcUrl = request.form.get('urls') if srcUrl: urls = srcUrl.split('|') for url in urls: if not localdomain_re.search(url.strip()): downfile = urllib.urlopen(url) fext = imageTypes[downfile.headers.getsubtype().lower()] rnd_name = '%s%s' % (gen_rnd_filename(), fext) with open(os.path.join(app.static_folder, 'upload', rnd_name), 'wb') as fp: fp.write(downfile.read()) urlreturn = url_for('static', filename='%s/%s' % ('upload', rnd_name)) urlout.append(urlreturn) else: urlout.append(url) result = '|'.join(urlout) return result
這裏有個簡單的DEMO:https://coding.net/wtx358/flask-xheditor-demo.git
雖然xhEditor已經再也不更新了,但仍不失爲一款優秀的富文本編輯器,它的文件上傳方式也值得借鑑。不過呢,項目中更多地會選擇CKEditor或者UEditor這類比較活躍的編輯器。