百度編輯器(Ueditor)最新版(1.4.3.3)插入錨點失敗緣由分析及BUG修復

用百度編輯器——Ueditor(版本1.4.3.3,2016-05-18日上線)插入錨點的時候,每次老是失敗,百思不得其解。經過分析Ueditor的代碼ueditor.all.js,能夠看出Ueditor插入錨點的過程,其實是一個img標籤和a標籤相互轉換的過程,其代碼以下: html

'anchor':{
   //cmd:命令字符串,name:錨點名稱
   execCommand:function (cmd, name) {
                  var range = this.selection.getRange(),img = range.getClosedNode();
                  if (img && img.getAttribute('anchorname')) {
                      if (name) {
                          img.setAttribute('anchorname', name);
                      } else {
                          range.setStartBefore(img).setCursor();
                          domUtils.remove(img);
                      }
                  } else {
                      if (name) {
                          //只在選區的開始插入
                          var anchor = this.document.createElement('img');
                          range.collapse(true);
                          domUtils.setAttributes(anchor,{
                              'anchorname':name,
                              'class':'anchorclass'
                          });
                          range.insertNode(anchor).setStartAfter(anchor).setCursor(false,true);
                      }
                  } 
                           ……git

分析上述代碼,插入錨點的過程實際上在Ueditor中顯示的時候實際上是插入了一個圖片(img元素),設置該img的anchorname屬性爲插入錨點的名字。生成的HTML代碼形如」<img class='anchorclass' anchorname='title_01'>「其中「title_01」即爲錨點的名字。代碼看起來是沒有問題的,筆者也屢次使用alert調試,運行過程當中是能夠獲得錨點的名稱‘name’的值的,可是在編輯器中查看源代碼的時候始終沒有anchorname屬性,因而筆者手動在獲得的img標籤中寫入anchorname的屬性值,結果切換到顯示界面又切換回HTML界面後,該屬性依然丟失,真可謂百思不得其解。接着查看針對插入錨節點時的輸入規則(inputRule)和輸出規則(outputRule)部分的代碼,能夠清晰的瞭解到輸出時Ueditor會將擁有anchorname屬性的img節點變成a(超級連接)節點,並將該img的anchorname屬性值做爲'a'的name屬性值,這樣就完成了一個圖像錨像一個真正錨的變換,代碼以下:github

outputRule: function(root){
          utils.each(root.getNodesByTagName('img'),function(a){
              var val;
              if(val = a.getAttr('anchorname')){
                  a.tagName = 'a';
                  a.setAttr({
                      anchorname : '',
                      name : val,
                      'class' : ''
                  })
              }
          })
      },dom

而輸入的時候使用的輸入規則(inputRule),是當用戶直接在其HTML源碼界面中輸入錨節點的代碼(好比:」<a name="title_01"></a>「)時,當用戶切換到顯示界面的時候,系統會自動將該錨點轉換成圖片錨,該圖片節點(img節點)的class="anchorclass",anchorname="title_01"(上述錨節點的name屬性值),代碼以下:xss

inputRule:function(root){
           utils.each(root.getNodesByTagName('a'),function(a){
               var val;
               if((val = a.getAttr('name')) && !a.getAttr('href')){
                   a.tagName = 'img';
                   a.setAttr({
                       anchorname :a.getAttr('name'),
                       'class' : 'anchorclass'
                   });
                   a.setAttr('name')
               }
           })
       },編輯器

這樣用戶看起來就有一個錨的圖片在剛纔插入錨的地方,而保存的時候仍然會使用outputRule,將該圖片變成一個真正的錨。this

代碼的實現看起來一點問題也沒有,但是爲何就是插入不了錨呢(實質上是在img節點中,不管如何也插入不了anchorname屬性,這點我在官網也嘗試過,也不行,能夠說結結實實是個BUG)。spa

正當我覺得該問題無解的時候,我忽然發現原來在使用Ueditor的時候,除了引入了Ueditor.all.js外還引入了一個配置文件Ueditor.config.js,我以爲看看這個文件的代碼,這一下,終於被我找到了緣由所在。原來在這個配置文件中定義了每一個HTML標籤的過濾規則,也就是某個HTML標籤只能有哪些屬性,因此當咱們加入其餘屬性的時候是會被編輯器過濾掉的,好比我給img添加的achorename屬性(也就是上述程序在講錨轉換成圖片的時候要插入的屬性),由於在img的屬性過濾的白名單中是沒有該屬性的,因此照成了插入的失敗,也照成了編輯器插入錨節點時出現的BUG。一樣,筆者還發如今‘a’標籤的白名單中是沒有‘name’屬性的,也就是編輯器默認狀況下是不能插入錨點的,將上述兩個屬性加入到配置文件中,問題得解,能夠自由的插入任何錨節點了。下面附上修改後的img和a標籤的白名單:.net

// xss 過濾是否開啓,inserthtml等操做調試

,xssFilterRules: true

//input xss過濾

,inputXssFilter: true

//output xss過濾

,outputXssFilter: true

// xss過濾白名單 名單來源: https://raw.githubusercontent.com/leizongmin

/js-xss/master/lib/default.js

,whitList: {

a:      ['target', 'href', 'title', 'class', 'style','name'],

……

img:    ['src', 'alt', 'title', 'width', 'height', 'id', '_src', 

          'loadingclass', 'class','anchorname']

固然還有其餘的一些白名單,因爲和本主題無關就再也不一一羅列。以上就是我解決Ueditor插入錨點BUG的過程,也許您有更好的方法,請給我留言,謝謝!

本文首發於頂求網,轉載請註明來源。

相關文章
相關標籤/搜索