跳到主要內容
黯羽輕揚每天積累一點點

CSST(CSS Text Transformation)

免費2016-05-14#CSS#JS#CSST是什么#跨域文本传输#跨域方法

CSST 的近義詞是 JSONP,而不是 SASS、PostCSS 之類的東西

##一.CSST是什麼

CSST 的近義詞是 JSONP,而不是 SASS、PostCSS 之類的東西。也就是說,JSONP 能做的,(CSS3 環境下)用 CSST 也可以做到

Ajax 不能跨域,而 JSONP 算是 Ajax 的跨域補丁(當然,還有其他跨域方法,但 JSONP 是應用最廣泛的)

CSST 最大的限制是只適用於支援 CSS3 的環境,但我們用不用它這不重要,思路與原理比較有意思

##二.實現原理

###1.用戶端(瀏覽器 JS)

  1. 發送請求

向 head 裡插入一個 <link>,透過 href 屬性發出請求

  1. 準備接收回應

建立一個看不見的 span,監聽其 animationstart 事件(所以需要 CSS3 環境)

###2.伺服器端(node/PHP...)

  1. 回傳樣式(將透過 id 套用給隱藏 span)

樣式內容分為兩部分:1. content(用 CSS 屬性 content 攜帶業務邏輯要回傳的字串);2. animation(通知用戶端,回應傳回了)

伺服器端只做這一件事,用戶端收到回應後,取出 span 的 content 內容,文字傳輸完成

###3.細節問題(技術手段)

  1. 怎麼監聽 <link> 載入完畢?

收集線上的資料,發現常見的方案是計時器或者用 onpropertychange、DOMAttrModified。

考慮是 CSS3 場景,取巧用動畫開始 (animationstart) 這個事件來捕獲。

onpropertychangeDOMAttrModified 事件以及更新的 MutationObserver 在相容性方面存在很多問題,而 animationstart 事件相容性相對較好(不支援 Android 2.3 及其以下版本,不支援 IE6-IE9),因為動畫事件是 CSS3 動畫模組規範的一部分,支援 CSS3 動畫的 UA 應該都支援對應的動畫事件

  1. 怎麼傳送特殊字元("、'、\、\n、\r、\t)?

Chrome、Safari 對 content 樣式屬性字元解析並不一致

為避免未知解析規則影響,統一使用 base64 編碼

瀏覽器環境下編碼/解碼 Base64 相對容易,也適用於其他需要支援特殊字元的場景

##三.優缺點

優點:如果介面被攻陷的話,後果比 JSONP 小一點(link 標籤比 script 標籤安全些,後者注入程式碼能直接執行,前者只影響樣式)

P.S. 如果介面都被攻陷了,這一點防禦措施興許還能起到什麼關鍵性作用嗎?

缺點:

  • 只支援 CSS3 環境

  • DOM 操作多於 JSONP(每次請求需要增加/刪除一個 link 一個 span,JSONP 每次只需要增加/刪除一個 script,而且隱藏 span 的增加/刪除以及樣式更新可能會導致頁面部分 reflow)

所以,不推薦使用 CSST,JSONP 明顯更方便實用,本文只是想說這種思路與原理值得了解

如果非要用的話,也應該考慮一下不支援/部分支援 CSS3 的 UA 的感受,需要完善特徵檢測(原專案暫時沒有添上):

var animation = false,
    animationstring = 'animation',
    keyframeprefix = '',
    domPrefixes = 'Webkit Moz O ms Khtml'.split(' '),
    pfx  = '',
    elm = document.createElement('div');

if( elm.style.animationName !== undefined ) { animation = true; }    

if( animation === false ) {
  for( var i = 0; i < domPrefixes.length; i++ ) {
    if( elm.style[ domPrefixes[i] + 'AnimationName' ] !== undefined ) {
      pfx = domPrefixes[ i ];
      animationstring = pfx + 'Animation';
      keyframeprefix = '-' + pfx.toLowerCase() + '-';
      animation = true;
      break;
    }
  }
}

(以上程式碼摘自 Detecting CSS animation support - CSS | MDN

更好的相容性需要手動重構程式碼,算了,了解下就好

###參考資料

評論

暫無評論,快來發表你的看法吧

提交評論