AngularJS'de bir değişkenten iframe src özniteliği nasıl ayarlanır


214

srcBir değişken bir iframe özniteliğini ayarlamak için çalışıyorum ve işe alamıyorum ...

İşaretleme:

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

kontrolörleri / 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 );

    }
}

Bu kodla iframe'in srcözelliğine hiçbir şey eklenmez . Sadece boş.

Güncelleme 1:$sce AppCtrl'e bağımlılığı enjekte ettim ve $ sce.trustUrl () artık hata atmadan çalışıyor. Ancak TrustedValueHolderType, gerçek bir URL eklemek için nasıl kullanılacağından emin değilim. Öznitelikte enterpolasyon kaşlı ayraçlar içinde $ sce.trustUrl () kullanın src="{{trustUrl(currentProjectUrl))}}"veya currentProjectUrl değerini ayarlarken denetleyicinin içinde yapsam da aynı tür döndürülür . Her ikisiyle de denedim.

Güncelleme 2: .toString () kullanarak url'yi TrustedUrlHolder'dan nasıl döndüreceğimizi anladım, ancak bunu yaptığımda, src özniteliğine geçirmeye çalıştığımda güvenlik uyarısını atar.

Güncelleştirme 3: Denetleyicide trustAsResourceUrl () kullanır ve ng-src özniteliğinde kullanılan bir değişkene iletirsem çalışır:

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

}

Sorunum bu şekilde çözülmüş gibi görünüyor, ancak nedenini tam olarak bilmiyorum.

Yanıtlar:


360

Ben işlevi o alıntı bakarak zanlısı trustSrcgelen trustSrc(currentProject.url)denetleyicisi tanımlı değil.

Sen enjekte etmek gerek $scehizmet denetleyicisi ve orada.trustAsResourceUrlurl

Denetleyicide:

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

Şablonda:

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

1
Tavsiye ettiğiniz gibi $ sce ile denedim. Hata iletisinin kaybolmasına neden olur, ancak iframe'in src özelliği hala boştur.
emersonthis

3
Kullanmayı deneyin trustAsResourceUrl.
musically_ut

9
... ama bunu ng-src özelliğine geçirdiğimde çalışıyor! Teşekkürler.
emersonthis

2
@Emerson trustAsResourceUrldöndüren bir $sce.RESOURCE_URLiçin gerekli olan iframe/ ' objectsda trustAsUrldöner bir $sce.URLgaranti daha zayıf bir tür (ve uygun olarak henüz kullanılmamış olan belgeler ).
musically_ut

1
ng-src, çift kıvırcık parantezleri kaldırmadıkça benim için çalışmadı (ng-src = "currentProjectUrl")
baacke

10

Öyle $scedış etki ile URL'leri engeller böyle vb XSS, Clickjacking gibi güvenlik açıklarını da açısal 1.2 varsayılan olarak etkindir oluyor önlemek için, angularjs için Sıkı Bağlamsal Kaçan hizmetleri sağlayan bir hizmet olduğunu hizmet.

Tamamen devre dışı bırakabilirsiniz, ancak önerilmez

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

daha fazla bilgi için https://docs.angularjs.org/api/ng/service/$sce


3

bu şekilde takip ediyorum ve benim için işi iyi, sizin için işe yarayacak mı,

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

Burada trustThisUrl sadece filtre,

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

2

Lütfen trustSrcişlev çağrısını kaldırın ve bu şekilde tekrar deneyin. {{trustSrc (currentProject.url)}} ile {{currentProject.url}} arasında. Bu bağlantıyı kontrol edin http://plnkr.co/edit/caqS1jE9fpmMn5NofUve?p=preview


Ancak Açısal Js 1.2 Belgelerine göre, srcurl almak için bir işlev yazmalısınız . Aşağıdaki koda bir göz atın.

Önce:

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

Ancak güvenlik nedeniyle aşağıdaki yöntemi önermektedirler

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()}}">

Belgeler, ng-srcveya öğesindeki birden fazla ifadeye bağlanma durumunda bu tavsiyeyi sunar src. Eğik 1.2 itibaren, tek tek ifade bağlanabilen srcve ng-srcve tavsiyeler gerekirse, bir fonksiyonu kullanarak koddan bir url almak etmektir.
musically_ut

Ancak kodunuzda bir hata olduğunu düşünüyorum. Denetleyici bu app.controller ('AppCtrl', function ($ scope) {}) gibi olmalıdır;
Sajith

1
Kontrolörler Global erişilebilir fonksiyonlar da olabilir.
musically_ut

Tamam. Bu bağlantıyı kontrol edin Kodunuzu dalgıç ile kontrol ettim. plnkr.co/edit/caqS1jE9fpmMn5NofUve
Sajith

Kodunuzda "trustSrc" işlevini fark ettim. Lütfen bu işlevi kaldırın ve bu şekilde tekrar deneyin. {{trustSrc (currentProject.url)}} ile {{currentProject.url}}
Sajith

0

şablon seç; iframe denetleyicisi, ng model güncellemesi

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

Bu bağlantıyı kontrol edin: http://plnkr.co/edit/TGRj2o?p=preview


0

Ayrıca gerekir $sce.trustAsResourceUrlveya iframe içindeki web sitesini açmaz:

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>

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.