前端用戶在寫文章時,有時候會需要往文章中插入圖片,editormd開源項目也提供了“添加圖片”的功能,當用戶點擊添加圖片按鈕后,會彈出一個窗口,圖片的來源支持兩種:一種是本地圖片,另一種是網絡圖片;添加后的圖片,我們還可以給它添加鏈接,業務對圖片進行描述。
- 網絡圖片
隨便從網上找一個圖片,復制圖片地址,黏貼至“圖片地址”欄里,完善圖片的其他兩個信息。
點擊確定后,editormd編輯器里就會多出一行圖片的信息,右邊預覽里就會顯示一張圖片,並且點擊圖片會跳轉到百度。
- 本地圖片
本地圖片的上傳相對網絡圖片來說要復雜的多,需要后端服務器處理用戶上傳過來的圖片,並保存到服務器指定文件夾中。本地圖片上傳的服務器后端地址,需要在前端edit-post.html模板中指定。
* 前端代碼:
1 //初始化編輯器 2 var testEditor; 3 $(function () { 4 testEditor = editormd("editormd", { 5 width: "100%", 6 height: 740, 7 path: '/static/editormd/lib/', 8 theme: "", 9 previewTheme: "", 10 editorTheme: "pastel-on-dark", 11 markdown: "", 12 codeFold: true, 13 saveHTMLToTextarea: true, // 保存 HTML 到 Textarea 14 searchReplace: true, 15 htmlDecode: "style,script,iframe|on*", // 開啟 HTML 標簽解析,為了安全性,默認不開啟 16 emoji: true, 17 taskList: true, 18 tocm: true, // Using [TOCM] 19 tex: true, // 開啟科學公式TeX語言支持,默認關閉 20 flowChart: true, // 開啟流程圖支持,默認關閉 21 sequenceDiagram: true, // 開啟時序/序列圖支持,默認關閉, 22 //配置本地圖片上傳參數 23 imageUpload: true, 24 imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp"], 25 imageUploadURL: "{{ url_for('main.upload') }}", //指定圖片要上傳到哪個視圖函數 26 onload: function () { 27 //圖片上傳成功后,可以做點什么。 28 } 29 }); 30 }); 31 //獲取編輯器內容 32 var blogcontent = encodeURIComponent(testEditor.getMarkdown());
* 后端代碼:
后端收到前端發過來的請求中包括一個變量為“editormd-image-file”的圖片數據,后端處理函數upload()會將上傳的文件獲取,並解析保存到指定的后台文件夾中。處理結果有兩種:1.失敗:返回帶兩個參數的json數據,2.成功:返回三個參數的json數據,其中包括圖片的url地址。圖片獲取處理函數image(name)中,我們對前端隱藏了實際的圖片物理路徑,而是通過處理函數來提供接口訪問。
后台返回給前端用戶的json數據
1 # -*- coding:utf-8 -*- 2 from flask import url_for, request, Response 3 from . import main 4 from flask_login import current_user, login_required 5 import os 6 7 @main.route('/upload', methods=['POST']) 8 @login_required 9 def upload(): 10 file = request.files.get('editormd-image-file') 11 if not file: 12 result = { 13 'success':0, 14 'message':'上傳失敗' 15 } 16 else: 17 ext = os.path.splitext(file.filename)[1] 18 filename = datetime.now().strftime('%Y%m%d%H%M%S') + ext 19 # 服務器后台處理文件夾和文件時,不能使用url_for()方法,需要服務器上的實際物理路徑 20 current_path = os.path.abspath(os.path.dirname(__file__)) 21 father_path = os.path.abspath(os.path.dirname(current_path) + os.path.sep) 22 # windows上的路徑時‘\’的 23 filedir = os.path.join(father_path, 'static\\asset\\img\\') 24 # 將圖片保存到當前用戶所在的目錄下 25 filepath = os.path.join(filedir, current_user.username) 26 if not os.path.exists(filepath): # 文件夾不存在,則創建 27 os.mkdir(filepath) 28 file.save(os.path.join(filepath, filename)) 29 result = { 30 'success':1, 31 'message':'上傳成功!', 32 'url':url_for('main.image', name=filename) 33 } 34 return result 35 # 隱藏后端靜態文件目錄的效果 36 @main.route('/image/<name>', methods=['GET']) 37 def image(name): 38 current_path = os.path.abspath(os.path.dirname(__file__)) 39 father_path = os.path.abspath(os.path.dirname(current_path) + os.path.sep) 40 filedir = os.path.join(father_path, 'static\\asset\\img\\') 41 filepath = os.path.join(filedir, current_user.username) 42 with open(os.path.join(filepath, name), 'rb') as f: 43 resp=Response(f.read(), mimetype="image/jpeg") 44 return resp
本地圖片的上傳,在上面代碼下,能很好地進行處理,效果如下:
- keep going.