angular 使用ueditor

最近在寫項目時,須要使用編輯器來編輯一個公司的描述信息,相似於這種效果:php

clipboard.png

在潘老師的指點下,一開始使用的TinyMCE這款編輯器,這也是一款很優秀的編輯器框架,可是後來提出了新的需求,在顯示公司詳情時,咱們還須要可以插入公司的位置信息,相似於這樣:css

圖片描述

要實現這效果,咱們須要調用百度地圖的api,潘老師還推薦了百度的一款編輯器:ueditor,既然如此,既然如此,那就使用這款ueditor編輯器好了。html

下載查看原型

我也不知道百度怎麼想的,官網的演示既上傳不了圖片,也不能搜索地圖,既然如此,只能把它下下來看看效果了。前端

clipboard.png

以前寫過php,就選擇了php版本下載,打開解壓,文件夾目錄以下:git

clipboard.png

dialogs: 彈出對話框對應的資源和JS文件
lang: 編輯器國際化顯示的文件
php或jsp或asp或net: 涉及到服務器端操做的後臺文件
themes: 樣式圖片和樣式文件
third-party: 第三方插件(包括代碼高亮,源碼編輯等組件)
ueditor.all.js: 開發版代碼合併的結果,目錄下全部文件的打包文件
ueditor.all.min.js: ueditor.all.js文件的壓縮版,建議在正式部署時採用
ueditor.config.js: 編輯器的配置文件,建議和編輯器實例化頁面置於同一目錄
ueditor.parse.js: 編輯的內容顯示頁面引用,會自動加載表格、列表、代碼高亮等樣式,具體看內容展現文檔
ueditor.parse.min.js: ueditor.parse.js文件的壓縮版,建議在內容展現頁正式部署時採用github

這裏php就是它的後端了,咱們有本身的後端,先不理會它,在這個目錄下使用http-serve,打開瀏覽器http://127.0.0.1:8080/就能看到原型了:
clipboard.pngweb

點開地圖,選擇動態地圖後點擊確認,可是卻沒有效果,緣由是由於動態地圖的實現原理是用<iframe>標籤加載上述dialogs文件夾下的/map/show.html,將經度和緯度經過url參數傳給show.html,它再調用百度地圖api將位置信息顯示出來,可是ueditor編輯器爲了防止xss攻擊,把<iframe>標籤過濾掉了。 若是沒有過濾掉,編輯器內容應該以下。spring

clipboard.png

好在有解決方法,還記得在咱們解壓的文件夾下有一個ueditor.config.js文件,這就是編輯器的配置文件,打開它在裏邊查找whitList這一項,這就是xss過濾的白名單,添加iframe['frameborder','border','marginwidth','marginheight','width','height','src','id'],
這一項,咱們的動態地圖就不會被過濾掉了。數據庫

clipboard.png
圖片描述

導入angular

由於咱們項目使用的是angular,因此須要把ueditor導入到咱們的項目來,將整個文件夾複製到assets下,並更名爲ueditor
clipboard.pngnpm

爲了方便,咱們使用 npm 下載 ngx-ueditor(能夠看一下文檔,挺少的)

npm install ngx-ueditor --save

在AppModule導入UEditorModule並配置:

imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    LandingPageModule,
    UEditorModule.forRoot({
      js: [
        `./assets/ueditor/ueditor.config.js`,
        `./assets/ueditor/ueditor.all.js`,
      ],
      // 默認前端配置項
      options: {
        UEDITOR_HOME_URL: './assets/ueditor/'
      }
    })
  ],

而後咱們在app.component.html使用

<ueditor [(ngModel)]="html"></ueditor>

若是你看到了編輯器,那就說明成功的把ueditor導入到angular了。

clipboard.png

配置後端

ueditor的後臺代碼都有它本身的規範,與咱們的後臺代碼規範不同,既然如此,只能修改它的開發代碼以適應咱們的後端了。
後端的配置,主要配置圖片,視頻的上傳和獲取,咱們只要保證咱們後臺的接口接收和返回的數據格式與它要求的一致就好了。
打開控制檯:

clipboard.png

報了一個404的錯誤,請求的路徑爲:
http://localhost:8030/php/controller.php?action=config&&noCache=1567606213473 ,這個請求是用來請求後端的配置的,ueditor編輯器在初始化時,就須要後端的配置來配置上傳的信息。

點開/php/config.json文件,這就是咱們要返回的後端配置。
clipboard.png
爲了方便,咱們直接返回這個配置信息。觀察上述控制檯,報錯的行數是在ueditor.all.js:8111:

clipboard.png

查看源代碼發現它根據一個路徑(後邊會修改這個)請求後臺的接口,並用返回來的json數據進行配置。因此在這裏,直接把json數據返回就好了。
assets/ueditor/php/config.json移動到assets/ueditor/下,修改上述代碼configUrl爲:

var configUrl = 'assets/ueditor/config.json',

這時候咱們就能成功使用圖片上傳的插件了。

clipboard.png

接下來,咱們還要配置後端上傳的接口,首先修改根路徑,在ueditor.config.js裏找到serverUrl這一項,能夠看到它的默認值是:serverUrl: URL + "php/controller.php",有關上傳的全部功能,都會經過
http://localhost:8030/php/controller.php?action=xxxx
等方式進行上傳,而action的名字就在後端配置config.json中,例如在config.json裏的上傳圖片這一項:

{
    /* 上傳圖片配置項 */
    "imageActionName": "uploadimage", /* 執行上傳圖片的action名稱 */
    "imageFieldName": "upfile", /* 提交的圖片表單名稱 */
    "imageMaxSize": 2048000, /* 上傳大小限制,單位B */
    "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上傳圖片格式顯示 */
    "imageCompressEnable": true, /* 是否壓縮圖片,默認是true */
    "imageCompressBorder": 1600, /* 圖片壓縮最長邊限制 */
    "imageInsertAlign": "none", /* 插入的圖片浮動方式 */
    "imageUrlPrefix": "", /* 圖片訪問路徑前綴 */
.....    
}

ueditor編輯器在一開始就要獲取config.json文件的緣由就是爲了配置後端的上傳接口,它會根據你在這裏定義的配置來進行文件的上傳.

首先,咱們先修改serverUrl的值,改成你後臺的地址,其次它的請求方法名是傳遞action=XXX參數,再由你後臺獲取這個參數進行判斷,而後執行你須要的操做的,可是咱們的後臺接口通常都是在url上以/action來區分你要請求的方法,因此,還得改一下它的請求方法。
搜索getActionUrl,能夠看到請求的接口地址都是從這裏返回的,所以,咱們只須要修改返回的格式就好了。

clipboard.png

改成:

serverUrl = serverUrl + '/' + (actionName || '');

此時編寫後臺接口,我用的是springboot:

@RestController
@RequestMapping("ueditor")
@Api(tags = "Ueditor 臨時上傳文件接口")
public class UeditorController {

    @Autowired
    AttachmentService attachmentService;

    @ApiOperation(value = "上傳圖片類型的附件", notes = "上傳圖片類型的附件", nickname = "Attachment_uploadImage")
    @PostMapping("/uploadImage")
    @ResponseStatus(HttpStatus.CREATED)
    public UeditorImage uploadImage(@RequestParam("file") MultipartFile[] submissions) {
        MultipartFile submission = submissions[0];
        Attachment attachment = this.attachmentService.uploadImage(submission);
        UeditorImage ueditorImage = new UeditorImage();
        ueditorImage.setState("SUCCESS");
        ueditorImage.setTitle(attachment.getSaveName());
        ueditorImage.setOriginal(submission.getOriginalFilename());
        ueditorImage.setUrl(attachment.getSavePath());
        return ueditorImage;
    }
}

// 須要返回此json數據 給ueditor顯示
class UeditorImage {
    private String state;
    private String url;
    private String title;
    private String original;

    public String getState() {
        return state;
    }
    public void setState(String state) {
        this.state = state;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getOriginal() {
        return original;
    }
    public void setOriginal(String original) {
        this.original = original;
    }
}

注意:
PostMapping必需要與config.json 裏的imageActionName一致。
@RequestParam("file")參數名必需要與imageFieldName一致。
返回json數據要與百度要求的json數據一致,否則前端沒法顯示。

好了,此時就能成功的上傳圖片了。此時咱們綁定的([ngmodel])=html,html中存放的就是編輯框內容的html代碼了,咱們只要保存這個值到數據庫,要顯示詳情的時候用<div [innerhtml]="xxxx"></div>就能夠成功顯示詳情了。

clipboard.png

注意,angular的innerhtml也會過濾掉iframe,所以咱們要使用angular內置方法來轉換咱們的描述文本,告訴angular這是安全的。

import {Component} from '@angular/core';
import {DomSanitizer} from '@angular/platform-browser';

@Component({
  selector: 'yzpf-root',
  template: '<div class="row col-md-6 offset-3" [innerHTML]="transform(html)">\n' +
    '</div>\n',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {

  html = '<p><img src="attachment/image/2019731/bdf4e0a70bd90c650fd32ebdc675c24c.png" title="" alt="6a600c338744ebf803157a9adef9d72a6059a72a.png" width="534" height="306"/></p><p>嗶哩嗶哩(英文名稱:bilibili,簡稱B站)現爲國內領先的年輕人文化社區,該網站於2009年6月26日建立,被粉絲們親切的稱爲「B站」。</p><p>B站的特點是懸浮於視頻上方的實時評論功能,愛好者稱其爲「彈幕」,這種獨特的視頻體驗讓基於互聯網的彈幕可以超越時空限制,構建出一種奇妙的共時性的關係,造成一種虛擬的部落式觀影氛圍,讓B站成爲極具互動分享和二次創造的文化社區。B站目前也是衆多網絡熱門詞彙的發源地之一。</p><p>2019年4月22日,針對「後臺源碼泄露」一事,B站在今晚已經作出迴應,其表示,經內部緊急覈查,確認該部分代碼屬於較老的歷史版本<span class="sup--normal" style="font-size: 12px; line-height: 0; position: relative; vertical-align: baseline; top: -0.5em; margin-left: 2px; color: rgb(51, 102, 204); cursor: pointer; padding: 0px 2px;">&nbsp;[1]</span><a class="sup-anchor" style="color: rgb(19, 110, 194); position: relative; top: -50px; font-size: 0px; line-height: 0;">&nbsp;</a>&nbsp;;5月29日,嗶哩嗶哩發佈通知稱,因彈幕系統技術升級,5月29日起至6月6日網站將暫時關閉彈幕功能</p><p><br/></p><p><br/></p><p>位置:</p><p><iframe src="./assets/ueditor/dialogs/map/show.html#center=116.404,39.915&zoom=10&width=530&height=340&markers=116.404,39.915&markerStyles=l,A" frameborder="0" width="534" height="344"></iframe></p>';

  title = 'platform';

  constructor(private sanitizer: DomSanitizer) {

  }


  transform(text: string) {
    return this.sanitizer.bypassSecurityTrustHtml(text);
  }
}

好了,這樣就能成功顯示咱們編輯的內容了,剩下的樣式調整就好了。

clipboard.png

相關文章
相關標籤/搜索