2013-09-27 17 views
7

我正在使用客戶端上的Angular(1.2 RC2)在CMS驅動的網站上工作。由於內容來自CMS,我不幸被迫在JSON字符串中使用接收HTML。大多數HTML被注入並渲染得很好,但圖像標籤的src已被剝離。從我讀過的內容來看,src應該以「unsafe:」爲前綴,如果這是Angular的XSS安全問題,則不會完全刪除。但我可能會誤解。Angular 1.2:ng-bind-html在img上刪除src屬性

我一直在這個問題一段時間,現在感覺我已經嘗試了一切從可信到徹底愚蠢。將我的CMS網址列入白名單,將所有內容白名單,禁用$ sce,強制HTML低谷$ sce.trustAsHtml()以及...迄今爲止,沒有運氣。由於該網站是由CMS驅動的,所以我不幸無法創建一個plunker /小提琴,但我希望一個善良的靈魂會盡力幫忙。

更新:忘了提及我也試過ng-src,效果相同。 更新II:如果我使用HTTPS,則會保留src屬性並顯示圖像。這是可以接受的,因爲它會在生產環境中運行HTTPS,但我仍然想知道爲什麼禁用$ sce不起作用。由瀏覽器(slide.body的含量)

<div class="row"> 
    <div class="col-md-6 visible-md visible-lg"> 
     <img alt="none" class="img-responsive"> 
    </div> 
    <div class="col-xs-12 col-md-6"> 
     <div class="itx-article-header"> 
      <h1>Sulvat Quis 1</h1> 

      <h2>– Nullam dictum ac enim</h2> 

     </div> 
     <p>Proin quis justo vel felis varius sodales sit amet ut diam.</p> 
    </div> 
</div> 

JADE(HTML)

.my-carousel(ng-controller='CarouselCtrl') 
    carousel(interval='myInterval') 
     slide(ng-repeat='slide in slides', active='slide.active') 
      .my-carousel-item(ng-bind-html='slide.body') 

角控制器

.controller('CarouselCtrl', ['$sce', 'Article', '$scope', 
    function($sce, Article, $scope) { 
     $scope.myInterval = -1; 
     $scope.slides = Article.query(
      {category: 'carousel'}, 
      function(data){ 
       for (var i = 0; i < data.length; i++) { 
        $scope.slides[i].body = $sce.trustAsHtml(data[i].body);      
       } 
      }, 
      function() { 
       // Fail 
      }); 
    }]) 
所見

HTML

示例JSON響應(幻燈片) 對不起,廣域箱,沒有設法格式化它。

{ 
"cmarId": 16, 
"corp": { 
    "corpId": 2, 
    "guiSelected": false 
}, 
"createdAt": "Sep 27, 2013", 
"articleTag": "slide-1", 
"headline": "Slide 1", 
"highlighted": false, 
    "body": "\u003cdiv class\u003d\"container my-carousel-container-small\"\u003e\r\n\u003cdiv class\u003d\"row\"\u003e\r\n\u003cdiv class\u003d\"col-md-6 visible-md visible-lg\"\u003e\u003cimg ng-src\u003d\"img/illustrative/laptop.jpg\" alt\u003d\"none\" class\u003d\"img-responsive\" /\u003e\u003c/div\u003e\r\n\u003cdiv class\u003d\"col-xs-12 col-md-6\"\u003e\r\n\u003cdiv class\u003d\"my-article-header\"\u003e\r\n\u003ch1\u003eSulvat Quis 1\u003c/h1\u003e\r\n\u003ch2\u003e– Nullam dictum ac enim\u003c/h2\u003e\r\n\u003c/div\u003e\r\n\u003cp\u003eProin quis justo vel felis varius sodales sit amet ut diam. Fusce auctor sapien nec purus sagittis, in venenatis turpis luctus. Nullam dictum ac enim sed commodo. Vivamus et placerat sapien.\u003c/p\u003e\r\n\u003c/div\u003e\r\n\u003c/div\u003e\r\n\u003c/div\u003e", 
"articlePriority": 0, 
"category": { 
    "cmcaId": 9, 
    "corp": { 
     "corpId": 2, 
     "guiSelected": false 
    }, 
    "name": "carousel", 
    "visibleInMenu": false 
}, 
"published": true 

}

+0

你嘗試'NG-src'? – kubuntu

+0

Yupp,仍然失蹤。 –

+0

你能告訴我們你用'$ sce.trustAsHtml()'完成了什麼嗎? –

回答

9

你錯過這裏通過$sce.trustAsResourceURL();信任圖片網址的一塊。有關文檔,請參見here

編輯:此外,它似乎並沒有將引號中的ng-src值(以及它作爲HTML屬性所需的引號)包裝起來。這是行不通的 - ng-src需要一個javascript字符串作爲表達式的最終結果,並且你提供了一個無效的javascript文字。

+0

就我所見,你應該只發送圖像url到上面提到的方法。我正在處理整個HTML字符串,我無法知道圖像是/是在哪裏。關於您的更新,哪裏缺少引號? –

+0

除非我可怕地誤讀了html blob,否則ng-src \ u003d \「img/explanatory/laptop.jpg \」只有外部雙引號。 –

+0

至於網址,你有點卡在那裏。您可以禁用清理(不推薦),也可以重新構建響應,以便爲各種原因(資源與鏈接)提供您需要信任的URL列表。 –

2

參考:AngularJS documentation for $sanitize有一個演示。在此演示中,如果使用src而不是ng-srcng-bind-html函數(它從$sce.trustAsHtml()返回對象),則圖像按預期方式顯示。


建議編輯:我會先用src取代ng-src

然後我會改變

for (var i = 0; i < data.length; i++) { 
    $scope.slides[i].body = $sce.trustAsHtml(data[i].body);      
} 

for (var i = 0; i < data.length; i++) { 
    $scope.slides[i].body = function() { 
     return $sce.trustAsHtml(data[i].body); 
    }; 
} 

最後,

.my-carousel-item(ng-bind-html='slide.body') 

將變爲

.my-carousel-item(ng-bind-html='slide.body()') 

我自己沒有測試過,但請讓我知道這是否有效。


編輯(2013-11-02):錯字固定 - I加入return到的功能示例。代碼應該按預期工作。

+0

你不使用Angular綁定的答案似乎沒有正確的路線。爲什麼你會放棄繞過該功能的綁定? –

+0

我真的不知道。我粘貼了'none'這個例子,它工作。只要我將'src'改爲'ng-src',圖像就會退回到替代文字。 –

+0

@TylerEich:如果您閱讀更新(在回覆之前發佈),您會看到我確實已經嘗試了src和ng-src,沒有區別。所以我在想,你繞過綁定的方式是它的工作原理。 –

2

見關於AngularUI討論此評論: https://github.com/angular-ui/bootstrap/issues/813#issuecomment-25760432

這是重新實現了老bind-html-unsafe功能,它是目前在AngularJS前1.2指令。最後,這將按照上面的建議做,但最小的麻煩。所以你可以使用ng-bind-html-unsafe,並且不要讓你的代碼在你的主代碼中添加$ sce旁路,從而降低可讀性。

也看到這個問題#1:

1

後搜索如何顯示通過所見即所得的編輯器上傳我的CMS程序 圖像的時間,我發現這個

.filter('toTrusted', ['$sce', function($sce) { 
    return function(text) { 
     return $sce.trustAsHtml(text); 
    }; 
}]); 
<div ng-bind-html="data | toTrusted"></div> 

希望它可以幫助