Cách đặt thuộc tính src iframe từ một biến trong AngularJS


214

Tôi đang cố gắng đặt srcthuộc tính của iframe từ một biến và tôi không thể làm cho nó hoạt động ...

Đánh dấu:

<div class="col-xs-12" ng-controller="AppCtrl">

    <ul class="">
        <li ng-repeat="project in projects">
            <a ng-click="setProject(project.id)" href="">{{project.url}}</a>
        </li>
    </ul>

    <iframe  ng-src="{{trustSrc(currentProject.url)}}">
        Something wrong...
    </iframe>
</div>

bộ điều khiển / app.js:

function AppCtrl ($scope) {

    $scope.projects = {

        1 : {
            "id" : 1,
            "name" : "Mela Sarkar",
            "url" : "http://blabla.com",
            "description" : "A professional portfolio site for McGill University professor Mela Sarkar."
        },

        2 : {
            "id" : 2,
            "name" : "Good Watching",
            "url" : "http://goodwatching.com",
            "description" : "Weekend experiment to help my mom decide what to watch."    
        }
    };

    $scope.setProject = function (id) {
        $scope.currentProject = $scope.projects[id];
        console.log( $scope.currentProject );

    }
}

Với mã này, không có gì được chèn vào srcthuộc tính của iframe . Nó chỉ trống.

Cập nhật 1: Tôi đã thêm phần phụ thuộc $scevào AppCtrl và $ sce.trustUrl () hiện hoạt động mà không gặp lỗi. Tuy nhiên, nó trả về TrustedValueHolderTypemà tôi không chắc chắn cách sử dụng để chèn URL thực tế. Loại tương tự được trả về cho dù tôi sử dụng $ sce.trustUrl () bên trong dấu ngoặc nội suy trong thuộc tính src="{{trustUrl(currentProjectUrl))}}"hoặc nếu tôi thực hiện bên trong bộ điều khiển khi đặt giá trị của currentProjectUrl. Tôi thậm chí đã thử nó với cả hai.

Cập nhật 2: Tôi đã tìm ra cách trả lại url từ TrustedUrlHolder bằng cách sử dụng .toString () nhưng khi tôi làm điều đó, nó sẽ đưa ra cảnh báo bảo mật khi tôi cố gắng chuyển nó vào thuộc tính src.

Cập nhật 3: Nó hoạt động nếu tôi sử dụng trustAsResourceUrl () trong bộ điều khiển và chuyển nó đến một biến được sử dụng bên trong thuộc tính ng-src:

$scope.setProject = function (id) {
    $scope.currentProject = $scope.projects[id];
    $scope.currentProjectUrl = $sce.trustAsResourceUrl($scope.currentProject.url);
    console.log( $scope.currentProject );
    console.log( $scope.currentProjectUrl );

}

Vấn đề của tôi dường như được giải quyết bằng cách này, mặc dù tôi không chắc tại sao.

Câu trả lời:


359

Tôi nghi ngờ khi xem đoạn trích rằng hàm trustSrctừ trustSrc(currentProject.url)không được xác định trong bộ điều khiển.

Bạn cần phải tiêm các $scedịch vụ trong bộ điều khiển và trustAsResourceUrlcác urlở đó.

Trong bộ điều khiển:

function AppCtrl($scope, $sce) {
    // ...
    $scope.setProject = function (id) {
      $scope.currentProject = $scope.projects[id];
      $scope.currentProjectUrl = $sce.trustAsResourceUrl($scope.currentProject.url);
    }
}

Trong Mẫu:

<iframe ng-src="{{currentProjectUrl}}"> <!--content--> </iframe>

1
Tôi đã thử nó với $ sce như bạn đề nghị. Nó khiến thông báo lỗi biến mất, nhưng thuộc tính src của iframe vẫn trống.
emersonthis

3
Hãy thử sử dụng trustAsResourceUrl.
musically_ut

9
... nhưng cái này hoạt động khi tôi chuyển nó vào thuộc tính ng-src! Cảm ơn.
emersonthis

2
@Emerson trustAsResourceUrltrả về một $sce.RESOURCE_URLcái cần thiết cho iframe/ objectstrong khi trustAsUrltrả về một $sce.URLloại bảo đảm yếu hơn (và hiện không được sử dụng theo tài liệu ).
Musically_ut

1
ng-src không hoạt động với tôi trừ khi tôi gỡ bỏ dấu ngoặc kép (ng-src = "currentProjectUrl")
baacke

10

Đây là $scedịch vụ chặn URL với các tên miền bên ngoài, đây là dịch vụ cung cấp dịch vụ Thoát khỏi bối cảnh nghiêm ngặt cho AngularJS, để ngăn chặn các lỗ hổng bảo mật như XSS, nhấp chuột, v.v. được bật theo mặc định trong Angular 1.2.

Bạn có thể vô hiệu hóa nó hoàn toàn, nhưng nó không được khuyến khích

angular.module('myAppWithSceDisabledmyApp', [])
   .config(function($sceProvider) {
       $sceProvider.enabled(false);
   });

để biết thêm thông tin https://docs.angularjs.org/api/ng/service/$sce


3

theo cách này tôi làm theo và nó hoạt động tốt với tôi, có thể nó sẽ làm việc cho bạn,

<iframe class="img-responsive" src="{{pdfLoc| trustThisUrl }}" ng-style="{
                height: iframeHeight * 0.75 + 'px'
            }" style="width:100%"></iframe>

ở đây tin tưởng ThisUrl chỉ là bộ lọc,

angular.module("app").filter('trustThisUrl', ["$sce", function ($sce) {
        return function (val) {
            return $sce.trustAsResourceUrl(val);
        };
    }]);

2

Vui lòng xóa cuộc gọi để trustSrchoạt động và thử lại như thế này. {{trustSrc (currentProject.url)}} đến {{currentProject.url}}. Kiểm tra liên kết này http://plnkr.co/edit/caqS1jE9fpmMn5NofUve?p=preview


Nhưng theo Tài liệu Angular Js 1.2, bạn nên viết một hàm để lấy srcurl. Có một cái nhìn về mã sau đây.

Trước:

Javascript

scope.baseUrl = 'page';
scope.a = 1;
scope.b = 2;

Html

<!-- Are a and b properly escaped here? Is baseUrl controlled by user? -->
<iframe src="{{baseUrl}}?a={{a}&b={{b}}"

Nhưng vì lý do bảo mật, họ khuyến nghị phương pháp sau

Javascript

var baseUrl = "page";
scope.getIframeSrc = function() {

  // One should think about their particular case and sanitize accordingly
  var qs = ["a", "b"].map(function(value, name) {
      return encodeURIComponent(name) + "=" +
             encodeURIComponent(value);
    }).join("&");

  // `baseUrl` isn't exposed to a user's control, so we don't have to worry about escaping it.
  return baseUrl + "?" + qs;
};

Html

<iframe src="{{getIframeSrc()}}">

Tài liệu cung cấp lời khuyên này trong trường hợp một ràng buộc với nhiều hơn một biểu thức trong ng-srchoặc src. Góc 1.2 trở đi, người ta có thể liên kết với chỉ một biểu thức trong srcng-srcvà những lời khuyên là để lấy một địa chỉ từ các mã sử dụng một chức năng, nếu cần thiết.
musically_ut

Nhưng tôi nghĩ rằng có một số sai lầm trong mã của bạn. Bộ điều khiển phải giống như app.controll này ('AppCtrl', function ($ scope) {});
Sajith

1
Bộ điều khiển cũng có thể là chức năng có thể truy cập toàn cầu .
Musically_ut

Đồng ý. Kiểm tra liên kết này tôi đã kiểm tra mã của bạn với plunker. plnkr.co/edit/caqS1jE9fpmMn5NofUve
Sajith

Tôi đã nhận thấy một hàm "trustSrc" trong mã của bạn. Vui lòng xóa chức năng đó và thử lại như thế này. {{trustSrc (currentProject.url)}} đến {{currentProject.url}}
Sajith

0

chọn mẫu; bộ điều khiển iframe, cập nhật mô hình ng

index.html

angularapp.controller('FieldCtrl', function ($scope, $sce) {
        var iframeclass = '';
        $scope.loadTemplate = function() {
            if ($scope.template.length > 0) {
                // add iframe classs
                iframeclass = $scope.template.split('.')[0];
                iframe.classList.add(iframeclass);
                $scope.activeTemplate = $sce.trustAsResourceUrl($scope.template);
            } else {
                iframe.classList.remove(iframeclass);
            };
        };

    });
    // custom directive
    angularapp.directive('myChange', function() {
        return function(scope, element) {
            element.bind('input', function() {
                // the iframe function
                iframe.contentWindow.update({
                    name: element[0].name,
                    value: element[0].value
                });
            });
        };
    });

iframe.html

   window.update = function(data) {
        $scope.$apply(function() {
            $scope[data.name] = (data.value.length > 0) ? data.value: defaults[data.name];
        });
    };

Kiểm tra liên kết này: http://plnkr.co/edit/TGRj2o?p=preview


0

Bạn cũng cần $sce.trustAsResourceUrlhoặc nó sẽ không mở trang web bên trong iframe:

angular.module('myApp', [])
    .controller('dummy', ['$scope', '$sce', function ($scope, $sce) {

    $scope.url = $sce.trustAsResourceUrl('https://www.angularjs.org');

    $scope.changeIt = function () {
        $scope.url = $sce.trustAsResourceUrl('https://docs.angularjs.org/tutorial');
    }
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="myApp" ng-controller="dummy">
    <iframe ng-src="{{url}}" width="300" height="200"></iframe>
    <br>
    <button ng-click="changeIt()">Change it</button>
</div>

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.