2013-09-27 48 views
7

Tôi đang làm việc trên trang web hướng CMS bằng Angular (1.2 RC2) ở phía máy khách. Vì nội dung xuất phát từ CMS, tôi không may bị buộc phải sử dụng nhận HTML trong JSON Strings. Hầu hết các HTML được tiêm và kết xuất tốt, nhưng các thẻ hình ảnh có src của họ bị tước đi. Từ những gì tôi đã đọc src nên đã được tiền tố với "không an toàn:", không loại bỏ hoàn toàn nếu đây là một vấn đề bảo mật XSS trong Angular .. nhưng tôi có thể bị nhầm lẫn.Góc 1,2: ng-bind-html loại bỏ thuộc tính src trên img

Tôi đã gặp vấn đề này một thời gian và cảm thấy tôi đã thử mọi thứ từ đáng tin cậy đến hết sức ngu ngốc. Đưa vào danh sách trắng url CMS của tôi, liệt kê tất cả mọi thứ, tắt $ sce, buộc máng html $ sce.trustAsHtml() và tốt ... Cho đến nay, không có may mắn. Khi trang web là CMS hướng tôi không may không thể tạo ra một plunker/fiddle, nhưng tôi hy vọng một linh hồn tử tế sẽ cố gắng giúp đỡ anyway.

Cập nhật: Quên đề cập đến rằng tôi cũng đã thử ng-src, cùng một hiệu ứng. Cập nhật II: Nếu tôi sử dụng HTTPS, thuộc tính src vẫn còn và hình ảnh được hiển thị. Điều này được chấp nhận vì nó sẽ chạy trên HTTPS trong sản xuất, nhưng tôi vẫn muốn biết tại sao việc vô hiệu hóa $ sce không hoạt động.

HTML như được thấy bởi trình duyệt (nội dung của 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') 

điều khiển góc

.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 
      }); 
    }]) 

Phản hồi JSON mẫu (Slide) Xin lỗi về hộp rộng, không quản lý định dạng được.

{ 
"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

Bạn đã thử 'ng-src'? – kubuntu

+0

Yupp, vẫn còn thiếu. –

+0

Bạn có thể cho chúng tôi biết bạn đã làm gì với '$ sce.trustAsHtml()'? –

Trả lời

9

Các mảnh bạn đang thiếu ở đây là tin tưởng url hình ảnh qua $sce.trustAsResourceURL();. Xem here để biết tài liệu liên quan.

EDIT: Ngoài ra, có vẻ như bạn không gói giá trị ng-src trong dấu ngoặc kép (cũng như các dấu ngoặc kép bắt buộc cho nó là thuộc tính HTML). Điều đó sẽ không hoạt động - ng-src mong đợi một chuỗi javascript là kết quả cuối cùng của biểu thức, và bạn đang cung cấp nó với một chữ javascript không hợp lệ.

+0

Theo tôi, tôi có thể thấy bạn chỉ được gửi url hình ảnh vào phương pháp được đề cập ở trên. Tôi đang làm việc với một chuỗi toàn bộ HTML mà tôi không có cách nào để biết nếu/nơi hình ảnh được. Liên quan đến cập nhật của bạn, có dấu ngoặc kép ở đâu? –

+0

Trừ khi tôi đã đọc sai các blob html, ng-src \ u003d \ "img/illustrative/laptop.jpg \" chỉ có dấu ngoặc kép bên ngoài. –

+0

Đối với url, bạn đang bị mắc kẹt ở đó. Bạn có thể vô hiệu hóa khử trùng (không được khuyến nghị) hoặc bạn có thể cấu trúc lại phản hồi để cung cấp cho bạn danh sách các url bạn cần tin cậy vì nhiều lý do khác nhau (tài nguyên so với liên kết). –

2

tham khảo: Các AngularJS documentation for $sanitize có một bản demo. Trong bản trình diễn này, nếu bạn sử dụng src thay vì ng-srcng-bind-html thành một hàm (trả về đối tượng từ $sce.trustAsHtml()), hình ảnh sẽ xuất hiện như mong đợi.


chỉnh sửa đề nghị: tôi lần đầu tiên sẽ thay thế ng-src với src.

Sau đó, tôi sẽ thay đổi

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); 
    }; 
} 

Cuối cùng, điều này

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

sẽ thay đổi để

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

Tôi chưa tự mình thử nghiệm, nhưng hãy cho tôi biết nếu công trình này hoạt động.


Chỉnh sửa (2013/11/02):Typo sửa chữa - tôi đã thêm return với ví dụ chức năng. Mã này sẽ hoạt động như mong đợi ngay bây giờ.

+0

Câu trả lời của bạn về việc không sử dụng các ràng buộc góc dường như không đi đúng tuyến đường. Tại sao bạn sẽ từ bỏ các ràng buộc để bỏ qua các tính năng? –

+0

Tôi thành thật không biết. Tôi đã dán 'none 'vào ví dụ và nó đã hoạt động. Ngay sau khi tôi thay đổi 'src' thành' ng-src', hình ảnh sẽ quay trở lại văn bản thay thế. –

+0

@TylerEich: Nếu bạn đọc bản cập nhật (đã được đăng trước câu trả lời của bạn), bạn sẽ thấy rằng tôi đã thực sự thử cả src và ng-src, không có sự khác biệt. Vì vậy, tôi nghĩ rằng cách của bạn bỏ qua các ràng buộc là những gì làm cho nó hoạt động. –

2

Xem nhận xét này vào các cuộc thảo luận AngularUI: https://github.com/angular-ui/bootstrap/issues/813#issuecomment-25760432

Nó là một chỉ thị mà reimplements tính năng cũ bind-html-unsafe mà đã có mặt ở AngularJS trước 1.2. Cuối cùng điều này sẽ làm tương tự như đề xuất ở trên nhưng với tối thiểu là rắc rối. Vì vậy, bạn chỉ có thể sử dụng ng-bind-html-unsafe và không làm cho mã của bạn ít có thể đọc được bằng cách thêm bỏ qua $ sce trong mã chính của bạn.

cũng Xem câu hỏi Stackoverflow này:

1

Sau giờ tìm kiếm làm thế nào để hiển thị hình ảnh được tải lên thông qua trình soạn thảo WYSIWYG cho ứng dụng CMS của tôi tôi thấy điều này

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

Hy vọng nó giúp

Các vấn đề liên quan