UEditor 之初體驗後記

来源:https://www.cnblogs.com/hanzongze/archive/2019/07/18/js-ueditor.html
-Advertisement-
Play Games

UEditor 的核心特點就是:產自大廠、開源免費、功能全面(相當全)、體驗較為切合國人習慣。只需要修改相應的後端代碼,即可把 UEditor/UMeditor 中的圖片上傳到諸如又拍雲 USS 或阿裡雲 OSS 等雲存儲伺服器上,既安全又經濟。 ...


本文初稿寫於 3 年前,近期重新編輯整理,併進一步完善補充而成。

1、UEditor 基本介紹

1.1、關於 UEditor

UEditor是由百度web前端研發部開發所見即所得富文本web編輯器,具有輕量,可定製,註重用戶體驗等特點,開源基於MIT協議,允許自由使用和修改代碼。

上面這句話出自 UEditor 官方。在我看來,UEditor 的核心特點就是:產自大廠、開源免費、功能全面(相當全)、體驗較為切合國人習慣。想瞭解 UEditor 的更多信息,可參考以下幾個鏈接:

另外,UEditor 官方還提供了一個 Mini 版,名字叫 UMeditor。說是為了滿足廣大門戶網站對於簡單發帖框,或者回覆框需求所定製的版本。主要改進點在載入速度和載入失敗率上,且功能與 UEditor 也略有不同,具體可參考 UMeditor 的 GitHub

1.2、UEditor 現狀

UEditor 的最新版本是 v1.4.3.3,UMEditor 的最新版本是 v1.2.3。最後一次發佈都在 2016 年下半年,都快 3 年沒更新了。不過基本功能該有的也都有,且社區也比較認同和推崇,有不少人或組織都提供了特色的改進版或增強版,官方也偶有跟進。

綜合來看,目前要在國內做相對複雜的資訊發佈或留言功能,UEditor/UMEditor 依然是最好的選擇之一。

2、UEditor 簡單使用

2.1、將 UEditor 源碼集成到項目中

如果你要在後端項目中集成 UEditor,那麼直接下載對應語言版本的源碼,解壓之後拷貝到項目中即可。有兩點需要註意:

  • 1、官方只提供了 PHP、ASP、ASP.NET、JSP 四個版本,社區里有人提供了 Note.js、Python 等語言的版本。
  • 2、官方說提供的所有後端代碼都僅為 DEMO 作用,切不可直接用到生產環境中。平心而論,ASP.NET 版的後端代碼寫的確實水,不過前端能寫出這些後端代碼就已經很牛掰了,我是把用到的那部分代碼從頭到尾改了一遍才用到生產環境中的。

如果你要在前端項目中集成 UEditor,那就看你需不需要上傳圖片等後端功能了。如果不需要,那麼直接拷貝到前端項目中即可。但如果需要,那就得確保跑前端的 Web 伺服器能解析對應的後端代碼了。

當然,如果你把 UEditor 單獨部署到一個支持後端的 Web 伺服器上也是可行的。另外,集成 UMeditor 的方法與集成 UEditor 方法完全一樣。

2.2、讓 UEditor 的 UI 呈現在頁面中

1、首先,需要在頁面中引入 UEditor 的 3 個 js 文件,示例如下:

<!-- 編輯器的配置文件,前端配置都在這個文件中,註釋十分豐富 -->
<script type="text/javascript" charset="utf-8" src="/ueditor-1.4.3/ueditor.config.js"></script>
<!-- 編輯器的源碼文件 -->
<script type="text/javascript" charset="utf-8" src="/ueditor-1.4.3/ueditor.all.min.js"></script>
<!-- 編輯器的中文語言包 -->
<script type="text/javascript" charset="utf-8" src="/ueditor-1.4.3/lang/zh-cn/zh-cn.js"></script>

2、然後,在頁面中需要呈現 UEditor 的地方放置如下“占位符”代碼(註意給個 ID,下一步要用):

<!-- 編輯器的容器 -->
<script id="editor" type="text/plain" style="width:800px; height:300px;"></script>

3、最後,通過一句實例化編輯器的代碼來獲得編輯器實例(頁面運行起來時 UI 就會呈現出來):

$(function () {
    var ue = UE.getEditor("editor"); // 創建編輯器實例(這裡的 editor 就是上一步中的 ID)
});

得到編輯器實例對象之後,就可以通過它來調用 UEditor 的哪些 API 了。具體有哪些 API 可用,參見 UEditor API

2.3、用 UEditor 的過程中遇到的兩個坑

1、坑一,獲取內容可以而設置內容卻報錯

我用getContent獲取編輯器的內容並存入資料庫,然後把存到資料庫中的內容用setContent賦給編輯器。結果運行起來發現保存入庫可以,而打開編輯頁面直接就報錯了,編輯器也沒顯示出來。

後來發現這個是因為編輯器還沒準備好,所以就不能賦值,只需要把賦值操作放到ready之後即可,示例代碼如下:

ue.addListener("ready", function () {
    ue.setContent("@Model.Content"); // 等編輯器準備好之後再賦值,否則報錯
});

為了寫這篇文章,我嘗試了重現那個錯誤,結果編輯器又顯示出來了,但依然會報錯,錯誤消息是“Uncaught TypeError: Cannot set property 'innerHTML' of undefined”。

從某種程度上說,這個問題並不算是坑。因為官方手冊中就有相關說明和建議——“對編輯器的操作最好在編輯器ready之後再做”,不過我這人特別怕麻煩,凡是能憑猜測搞定的就不願細看文檔,所以第一次用的時候就掉坑了。

2、坑二,編輯器內顯示的是的 HTML,而不是文本內容

一開始還懷疑這會不會是 UEditor 的 Bug,直到把這個問題解決之後,反過來想才發現這裡面其實隱含了一個容易被忽略的“常識”,那就是網頁的模版引擎一般都會編碼字元串,比如我曾用過的 WebForms、NVelocity 和 RazorEngine 都是這樣。

換句話說,這時候編輯器拿到的是經過編碼之後 HTML,也就是說只要我們能確保編輯器拿到的是編碼前的 HTML 就行了。當然一開始我還沒想到是這個原因,於是我的解決辦法是根據曾使用其它編輯器的經驗試出來的,就是直接把內容放到script標簽中,示例代碼如下:

<script id="editor" type="text/plain" style="width:800px;height:300px;">
    @WebTools.RazorHelper.Raw(Model.Segment.Note)
</script>

在我意識到這個問題的始作俑者是網頁模版引擎而不是 UEditor 的時候,我做瞭如下測試:

ue.addListener("ready", function () {
    editor.setContent("@WebTools.RazorHelper.Raw(Model.Segment.Note)");
});

果然也是 OK 的,這也進一步證明瞭我的猜想是正確的!

2.4、將 UEditor 中的圖片上傳到雲伺服器上

由於 UEditor 預設是將圖片上傳到網站根目錄下的一個子文件夾中,如果是企業內部的信息系統,這麼做也還行,但如果是互聯網項目,這種做法就顯得既不安全、也不經濟的了,最好還是上傳到雲伺服器上。

要把 UEditor 中的圖片上傳到雲伺服器上,只需要修改後端代碼的上傳邏輯即可。我做過用 ASP.NET 把 UEditor 1.4.3 中的圖片上傳到 又拍雲 USS 和把 UMeditor 1.2.2 中的圖片上傳到 阿裡雲 OSS,其實思路是一樣的。

UEditor 的 ASP.NET 核心上傳邏輯在UploadHandler類的Process方法中,將上傳圖片到本地的那部分代碼替換成如下示例代碼即可。

try {
    // 校驗文件類型、文件大小等......
    String fileMd5 = StringSecurity.GetMd5(uploadFileBytes); // 用文件的 MD5 值做文件名
    String fileName = fileMd5 + Path.GetExtension(uploadFileName);
    String filePath = $"/images/{DateTime.Now.ToString("yyMMdd")}/{fileName}";
    // 調用又拍雲的 SDK 來上傳文件
    UpYun upyun = new UpYun("bucketname", "username", "password");
    upyun.setContentMD5(fileMd5);
    bool upyunResult = upyun.writeFile(filePath, uploadFileBytes, true);
    // ......
} catch (Exception e) {
    logger.Error("文件上傳失敗!", e);
    // ......
}

UMeditor 的 ASP.NET 核心上傳邏輯在Uploader類的upFile方法中,將上傳圖片到本地的那部分代碼替換成如下示例代碼即可。

try {
    // 校驗文件類型、文件大小等......
    String fileName = $"{GuidHelper.LowerPureString}.{getFileExt()}";
    String filePath = $"images/{DateTime.Now.ToString("yyMMdd")}/{fileName}";
    // 調用阿裡雲的 SDK 來上傳文件
    var client = new OssClient(SrcPoint, AccessKeyId, AccessKeySecret, 
        new Aliyun.OSS.Common.ClientConfiguration() { IsCname = true });
    var putResult = client.PutObject(SrcBucket, filePath, uploadFile.InputStream);
    // ......
    var uri = client.GeneratePresignedUri(SrcBucket, filePath);
    URL = uri.GetLeftPart(UriPartial.Path); // 將文件路徑賦值給編輯器引用的變數
} catch (Exception e) {
    logger.Error("文件上傳失敗!", e);
    // ......
}

可能你看到本文時,又拍雲和阿裡雲的雲存儲 SDK 已經做了較大改動,這裡附上二者的 GitHub 鏈接:

3、Web 編輯器雜談

3.1、我與 UEditor 的曲折歷程

2016 年初,我基於學習的目的,業餘做了一個帶新聞發佈功能的網站。在這之前,我曾先後用過 FreeTextBoxFCKeditor(已更名為 CKEditor),印象中都還不錯,但也都有著這樣或者那樣的問題,比如 CKEditor 中空格變問號的問題

我上網搜了一下,發現大家對 UEditor 的評價還不錯,於是決定 Web 編輯器就用 UEditor,由於是第一次用,過程相對曲折。做完新聞發佈功能之後,就順帶記錄了一下,也就是本文初稿。

兩年之後,也就是去年,公司要做個帶資訊發佈功能的媒體網站,在我的建議下,最終選用了 UMeditor。但整個團隊除我之外都沒用過,尤其是那幾個前端,連富文本編輯器是啥都不知道,最後就由我負責帶領前端來做這塊兒的功能。

因為這次做的是實際項目,公司的編輯們都在用,後臺的 UI 框架也由 jQuery 版的 EasyUI 變成了 React 版的 Ant Design,所以遇到的細節問題也比較多。其中對編輯器的各種配置和後端改造,都是由我統一解決好再跟前端對接的。

又過了一年,也就是本月初,我在整理資料時再次看到了本文初稿。瞬間就想起我去年用 UMeditor 的過程中也做過一些記錄,然後就想著乾脆把兩次的記錄整合起來,結果怎麼都找不到去年的記錄,只好作罷。也許還留在那家公司的電腦里吧!

3.2、CKEditor 空格變問號的原因及解決辦法

經查,導致該問題的根本原因是編碼轉換。在 UTF-8 里有一個特殊的編碼0xC2 0xA0,轉換成字元的時候,表現為一個空格,跟普通的半形空格一樣,不同的是它的寬度不會被壓縮,因此常被用來做網頁排版。而在 GB2312、Unicode 等字元集中卻沒有這個編碼,因此如果簡單地進行編碼轉換,這個編碼就會被替換成問號。

前些年在實際項目中還遇到過更奇葩的情況,文章保存之後,內容中的問號就全都沒了。後來發現是別人也遇到了空格變問號的問題,但選錯瞭解決方案,他是直接把問號又替換成空格,結果正常的問號也被斃掉了。

正確的做法是,用 UTF-8 格式的編碼進行替換,把那個特殊的空格替換為普通的空格,如果是 HTML 字元串,那就替換為&nbsp;。C# 代碼替換 HTML 字元串的示例如下:

byte[] space = new byte[]{0xc2,0xa0};
string utfSpace = Encoding.GetEncoding("UTF-8").GetString(space);
htmlStr = htmlStr.Replace(utfSpace,"&nbsp;");

註意:在替換之前不能進行編碼轉換,一定要繼續使用 UTF-8 編碼。如果已經轉換成其它編碼,那就徹底沒救了,因為這時候錯誤的問號和正常的問號之間已經沒有分別了。

本文鏈接http://www.cnblogs.com/hanzongze/p/js-ueditor.html
版權聲明:本文為博客園博主 韓宗澤 原創,作者保留署名權!歡迎通過轉載、演繹或其它傳播方式來使用本文,但必須在明顯位置給出作者署名和本文鏈接!個人博客,能力有限,若有不當之處,敬請批評指正,謝謝!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 列表是一個可以修改的,元素以逗號分割,用中括弧包圍的有序序列 格式:變數名 = [元素1,元素2,元素3,...] 列表序列操作: 1.相加: 2.重覆: 3.索引: 4.修改: 列表方法: 1.增加操作: append:追加,在列表尾部加入指定元素 append方法直接在原列表上做修改,返回值是N ...
  • 第九章併發編程 同一個程式執行多次是多個進程 9.1 開啟子進程的兩種方式 服務端目標: 1、不間斷地提供服務 2、服務端要支持高併發+高性能 一個進程在運行過程中開啟了子進程(如nginx開啟多進程,os.fork,subprocess.Popen等) 父進程發起請求,操作系統創建子進程 方式一: ...
  • 平面上有若幹個矩形,求矩形相互覆蓋的面積。為方便起見,矩形的邊均平行於坐標軸。 我們根據容斥原理,矩形相互覆蓋的面積即為所有矩形的面積和減去所有矩形所覆蓋的面積即可。 而現在問題是如何求得所有矩形所覆蓋的面積。即 讓我們人類去做,由於這是個由矩形拼接成的多邊形,很難去直接求它的面積,求該圖形的面積一 ...
  • 1.見名知意 起一個有意義的名字,儘量做到看一眼就知道是什麼意思 2.下劃線命名法 所有單詞小寫,單詞間用_連接 用於變數、函數的命名 3.大駝峰命名法 每個單詞直接連接,每個單詞首字母大寫 用於類的命名 補充: 1.以單_開頭的變數名_x不會被from module import * 語句導入 2 ...
  • x86 64數據格式、通用寄存器與操作數格式 數據格式 ​ Intel用術語“字(word)”表示16位數據類型,32位為“雙字(double words)”,64位數為“四字(quad words)”。 | C聲明 | Intel數據類型 | 彙編代碼尾碼 | 大小(位元組) | | : : | : ...
  • C++中經常會用到標準庫函數庫(STL)的string字元串類,跟其他語言的字元串類相比有所缺陷。這裡就分享下我經常用到的兩個字元串截斷函數: include include include include using namespace std; //根據字元切分string,相容最前最後存在字元 ...
  • 上次給大家分享了小白建站如何選擇虛擬空間及伺服器,及購買功能變數名稱的基礎知識,這些是硬性要求,你的網站要想運行起來,硬體只是基礎,真正的技術是軟體,關於PHP軟體開發技術,後面我們會慢慢的分享給大家,今天主要給大家分享的是,如何在你伺服器配置PHP運行的環境,有哪種模式,如何選擇呢? ...
  • C#是跟著楊老師的教程走的,在這裡感謝一下老師的無私奉獻,他的cnblog地址:>cgzl,他的B站地址:>solenovex。 進入正題: Delegate表示委托,委托是一種數據結構,它引用靜態方法或引用類實例及該類的實例方法。(引用官方文檔的英文原話) Represents a delegat ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...