詳解AngularJs中$sce與$sceDelegate上下文轉(zhuǎn)義服務(wù)
一、嚴(yán)格的上下文轉(zhuǎn)義服務(wù)
嚴(yán)格的上下文轉(zhuǎn)義(SCE)是一種需要在一定的語境中導(dǎo)致AngularJS綁定值被標(biāo)記為安全使用語境的模式。由用戶通過ng-bind-html
綁定任意HTML語句就是這方面的一個(gè)例子。我們稱這些上下文轉(zhuǎn)義為特權(quán)或者SCE。
二、$sce
$sce 服務(wù)是AngularJs提供的一種嚴(yán)格上下文轉(zhuǎn)義服務(wù)。
下面代碼是簡化了的ngBindHtml實(shí)現(xiàn)(當(dāng)然,這不是完整版ngBindHtml源碼):
var ngBindHtmlDirective = ['$sce', function($sce) { return function(scope, element, attr) { scope.$watch($sce.parseAsHtml(attr.ngBindHtml), function(value) { element.html(value || ''); }); }; }];
支持哪些信任的上下文類型?
$sce.HTML
將HTML代碼安全的綁定到應(yīng)用程序中。
$sce.CSS
將CSS樣式代碼安全的綁定到應(yīng)用程序中。
$sce.URL
將URL安全的綁定到應(yīng)用程序中并保證其可用。比如(href,src)
$sce.RESOURCE_URL
將RESOURCE_URL安全的綁定到應(yīng)用程序中并保證其可用。比如(ng-href,ng-src)
$sce.JS
將JAVASCRIPT代碼安全的綁定到應(yīng)用程序中。
如何使$sce服務(wù)可用或者不可用?
angular.module(“myApp”,[]).config([“$sceProvider”,function($sceProvider){ $sceProvider.enabled(true/false); }]);
使用:$sce();
方法:
isEnabled();
返回一個(gè)boolean,指示是否可啟用SCE。
parseAs(type,expression);
將Angular表達(dá)式轉(zhuǎn)換為一個(gè)函數(shù)。這類似$parse解析并且當(dāng)表達(dá)式是常量時(shí)是相同的。否則,它將調(diào)用$sce.getTrusted(type,result)
將表達(dá)式包裝。
type:在SCE的上下文的使用的結(jié)果的類型。
expression:被編譯的字符串表達(dá)式。
trustAs(type,value);
代表$sceDelegate.trustAs。
type:上下文中能安全的被使用的值,如url,resourceUrl,html,js和css。
value:需要被認(rèn)為是安全或者值的信賴的值。
trustAsHtml(value);
$sceDelegate.trustAs($sce.HTML,value)的快捷方式。
value:被信任的值。
trustAsUrl(value);
$sceDelegate.trustAs($sce.URL,value)的快捷方式。
value:被信任的值。
trustAsResourceUrl(value);
$sceDelegate.trustAs($sce.RESOURCE_URL,value)的快捷方式。
value:被信任的值。
trustAsJs(value);
$sceDelegate.trustAs($sce.JS,value)的快捷方式。
value:被信任的值。
getTrusted(type,maybeTrusted);
代表$sceDelegate.getTrusted。因此,得到了$sce的結(jié)果。如果查詢的上下文類型是一個(gè)創(chuàng)造型的類型,則調(diào)用trustAs()并且返回原來提供的值。如果這個(gè)條件不滿足,則拋出一個(gè)異常。
getTrustedHtml(value);
$sceDelegate.getTrusted ($sce.HTML,value)的快捷方式。
value:通過$sce.getTrusted執(zhí)行后的值。
getTrustedCss(value);
$sceDelegate.getTrusted ($sce.CSS,value)的快捷方式。
value:通過$sce.getTrusted執(zhí)行后的值。
getTrustedUrl(value);
$sceDelegate.getTrusted ($sce.URL,value)的快捷方式。
value:通過$sce.getTrusted執(zhí)行后的值。
getTrustedResourceUrl(value);
$sceDelegate.getTrusted ($sce.RESOURCE_URL,value)的快捷方式。
value:通過$sce.getTrusted執(zhí)行后的值。
getTrustedJs(value);
$sceDelegate.getTrusted ($sce.JS,value)的快捷方式。
value:通過$sce.getTrusted執(zhí)行后的值。
parseAsHtml(expression);
$sce.parseAs ($sce.HTML,value)的快捷方式。
value:被編譯的字符串表達(dá)式。
parseAsCss(expression);
$sce.parseAs ($sce.CSS,value)的快捷方式。
value:被編譯的字符串表達(dá)式。
parseAsUrl(expression);
$sce.parseAs ($sce.URL,value)的快捷方式。
value:被編譯的字符串表達(dá)式。
parseAsResourceUrl(expression);
$sce.parseAs ($sce.RESOURCE_URL,value)的快捷方式。
value:被編譯的字符串表達(dá)式。
parseAsJs(expression);
$sce.parseAs ($sce.JS,value)的快捷方式。
value:被編譯的字符串表達(dá)式。
使用方式:
<div ng-app="Demo" ng-controller="testCtrl as ctrl"> <textarea ng-model="ctrl.jsContext"></textarea> <pre ng-bind="ctrl.jsBody"></pre> <button ng-click="ctrl.runJs()">Run</button> <div ng-bind-html="ctrl.htmlText" class="myCss"></div> </div>
(function () { angular.module('Demo', []) .controller('testCtrl', ["$sce","$scope",testCtrl]); function testCtrl($sce,$scope) { var vm = this; $scope.$watch("ctrl.jsContext",function(n){ vm.jsBody = n; }); this.runJs = function() { eval(vm.jsBody.toString()); }; vm.htmlText = "<h2>Hello World</h2>"; vm.htmlText =$sce.trustAsHtml(this.htmlText); } }());
放在filter使用:
<div ng-app="Demo" ng-controller="testCtrl as ctrl"> <div ng-bind-html="ctrl.htmlText | trust:'html'"></div> </div>
(function () { angular.module('Demo', []) .filter("trust",["$sce",trust]) .controller('testCtrl', testCtrl); function trust($sce){ return function(value,type){ return $sce.trustAs(type,value); } }; function testCtrl() { this.htmlText = "<h2>Hello World</h2>"; } }());
上面是一個(gè)將不被Angular認(rèn)定為信任的HTML代碼字符串通過$sce設(shè)置為信任的HTML代碼并且插入的例子,這里用了個(gè)小技巧,也就沒在controller進(jìn)行這步操作了,直接放到一個(gè)filter服務(wù)內(nèi),只要在需要的地方過濾下即可,并且可指定類型,這里寫成統(tǒng)一動態(tài)選擇類型了。那么在啥時(shí)候需要用到這兩個(gè)服務(wù)呢?在當(dāng)使用ng-bind-html綁定html時(shí)報(bào)錯(cuò):Error: [$sce:unsafe]Attempting to use an unsafe value in a safe context. 的時(shí)候使用。
三、$sceDelegate
$sceDelegate是一個(gè)AngularJs為$sce服務(wù)提供嚴(yán)格的上下文轉(zhuǎn)義服務(wù)的服務(wù)。
通常,你會配置或者重寫$sceDelegate去代替$sce服務(wù)以定制AngularJs中的嚴(yán)格的上下文轉(zhuǎn)義機(jī)制。當(dāng)$sce提供眾多的快捷方式,你其實(shí)只需要重寫三個(gè)核心功能(trustAs,getTrusted和valueOf)來替代事件的工作方式,因?yàn)?sce代表了$sceDelegate的這些操作。
當(dāng)你完成了重寫或配置$sceDelegate用來改變$sce的行為時(shí),一般情況下,需要配置$sceDelegateProvider以代替你用于裝載可信任的AngularJs資源(如template)的白名單和黑名單。
使用:$sceDelegate();
方法:
trustAs(type,value);
返回一個(gè)在angular中作為指定的使用嚴(yán)格的上下文轉(zhuǎn)義服務(wù)上下文中的值的對象使用。
type:上下文中能安全的被使用的值,如url,resourceUrl,html,js和css。
value:需要被認(rèn)為是安全或者值的信賴的值。
valueOf(value);
如果傳遞的參數(shù)被上一個(gè)$sceDelegate.trustAs
調(diào)用返回,返回已通過$sceDelegate.trustAs
的值。否則返回原先的值。
value:上一個(gè)$sceDelegate.trustAs
調(diào)用的結(jié)果或者其他任何結(jié)果。
getTrusted(type,maybeTrusted);
如果查詢的上下文類型是一個(gè)創(chuàng)造型的類型,得到$sceDelegate調(diào)用的結(jié)果并返回最初提供的值。如果這個(gè)條件不滿意,拋出一個(gè)異常。
type:需要用到的值的類型。
value:上一個(gè)$sceDelegate.trustAs
調(diào)用的結(jié)果或者其他任何結(jié)果。
使用代碼(配置白名單/黑名單):
angular.module('myApp', []).config([“$ sceDelegateProvider”,function($sceDelegateProvider) { $sceDelegateProvider.resourceUrlWhitelist([“whitelist value”]); $sceDelegateProvider.resourceUrlBlacklist([“blacklist value”]); }]);
總結(jié)
以上就是這篇文章的全部內(nèi)容,希望能對大家的學(xué)習(xí)或者工作帶來一定的幫助,如果有疑問大家可以留言交流。
相關(guān)文章
Angularjs全局變量被作用域監(jiān)聽的正確姿勢
這篇文章主要介紹了Angularjs全局變量被作用域監(jiān)聽的正確姿勢的相關(guān)資料,需要的朋友可以參考下2016-02-02Angularjs實(shí)現(xiàn)帶查找篩選功能的select下拉框示例代碼
這篇文章主要介紹了Angularjs實(shí)現(xiàn)帶查找篩選功能的select下拉框的詳細(xì)過程及示例代碼,文中通過示例介紹的很詳細(xì),相信會對大家學(xué)習(xí)使用Angularjs具有一定的參考借鑒價(jià)值,有需要的朋友們可以一起來看看。2016-10-10AngularJS之自定義服務(wù)詳解(factory、service、provider)
本篇文章主要介紹了AngularJS之自定義服務(wù)詳解(factory、service、provider),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04AngularJS實(shí)現(xiàn)tab選項(xiàng)卡的方法詳解
這篇文章主要介紹了AngularJS實(shí)現(xiàn)tab選項(xiàng)卡的方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了AngularJS實(shí)現(xiàn)tab選項(xiàng)卡的原理、實(shí)現(xiàn)技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下2017-07-07Angularjs實(shí)現(xiàn)下拉框聯(lián)動的示例代碼
本篇文章主要介紹了Angularjs下拉框聯(lián)動的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-08-08AngularJS實(shí)踐之使用NgModelController進(jìn)行數(shù)據(jù)綁定
大家都知道AngularJS中的指令是其尤為復(fù)雜的一個(gè)部分,但是這也是其比較好玩的地方。這篇文章我們就來說一說如何在我們自定義的指令中,利用ngModel的controller來做雙向數(shù)據(jù)綁定,本文對大家學(xué)習(xí)AngularJS具有一定的參考借鑒價(jià)值,有需要的朋友們可以參考借鑒。2016-10-10