Cara mengatur atribut iframe src dari variabel di AngularJS

214

Saya mencoba mengatur srcatribut iframe dari suatu variabel dan saya tidak bisa membuatnya berfungsi ...

Markup:

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

pengendali / 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 );

    }
}

Dengan kode ini, tidak ada yang dimasukkan ke srcatribut iframe . Itu hanya kosong.

Pembaruan 1: Saya menyuntikkan $sceketergantungan ke AppCtrl dan $ sce.trustUrl () sekarang berfungsi tanpa membuang kesalahan. Namun ia mengembalikan TrustedValueHolderTypeyang saya tidak yakin bagaimana menggunakannya untuk memasukkan URL yang sebenarnya. Jenis yang sama dikembalikan apakah saya menggunakan $ sce.trustUrl () di dalam kurung interpolasi dalam atribut src="{{trustUrl(currentProjectUrl))}}"atau jika saya melakukannya di dalam controller ketika menetapkan nilai currentProjectUrl. Saya bahkan mencobanya dengan keduanya.

Pembaruan 2: Saya menemukan cara mengembalikan url dari dipercayaUrlHolder menggunakan .toString () tetapi ketika saya melakukan itu, ia melemparkan peringatan keamanan ketika saya mencoba meneruskannya ke atribut src.

Pembaruan 3: Ini berfungsi jika saya menggunakan trustAsResourceUrl () di controller dan meneruskannya ke variabel yang digunakan di dalam atribut 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 );

}

Masalah saya tampaknya diselesaikan dengan ini, meskipun saya tidak yakin mengapa.

emersonthis
sumber

Jawaban:

359

Saya curiga melihat kutipan bahwa fungsi trustSrcdari trustSrc(currentProject.url)tidak didefinisikan di controller.

Anda perlu menyuntikkan $scelayanan di controller dan trustAsResourceUrldi urlsana.

Di controller:

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

Dalam Templat:

<iframe ng-src="{{currentProjectUrl}}"> <!--content--> </iframe>
musically_ut
sumber
1
Saya mencobanya dengan $ sce seperti yang Anda rekomendasikan. Ini menyebabkan pesan kesalahan hilang, tetapi atribut src iframe masih kosong.
emersonthis
3
Coba gunakan trustAsResourceUrl.
musically_ut
9
... tapi yang ini berfungsi ketika saya meneruskannya ke atribut ng-src! Terima kasih.
emersonthis
2
@Emerson trustAsResourceUrlmengembalikan $sce.RESOURCE_URLyang diperlukan untuk iframe/ objectssementara trustAsUrlmengembalikan $sce.URLyang merupakan jenis jaminan yang lebih lemah (dan saat ini tidak digunakan sesuai dokumentasi ).
musically_ut
1
ng-src tidak bekerja untuk saya kecuali saya menghapus kurung kurawal ganda (ng-src = "currentProjectUrl")
baacke
10

Ini adalah $scelayanan yang memblokir URL dengan domain eksternal, ini adalah layanan yang menyediakan layanan Pelarian Kontekstual Strict ke AngularJS, untuk mencegah kerentanan keamanan seperti XSS, clickjacking, dll. Diaktifkan secara default di Angular 1.2.

Anda dapat menonaktifkannya sepenuhnya, tetapi tidak disarankan

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

untuk info lebih lanjut https://docs.angularjs.org/api/ng/service/$sce

Mohamed Selim
sumber
3

dengan cara ini saya ikuti dan itu bekerja untuk saya baik-baik saja, semoga akan bekerja untuk Anda,

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

di sini trustThisUrl hanya menyaring,

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

Harap hapus panggilan untuk trustSrcberfungsi dan coba lagi seperti ini. {{trustSrc (currentProject.url)}} ke {{currentProject.url}}. Periksa tautan ini http://plnkr.co/edit/caqS1jE9fpmMn5NofUve?p=preview


Tetapi menurut Dokumentasi Angular Js 1.2, Anda harus menulis fungsi untuk mendapatkan srcurl. Lihatlah kode berikut.

Sebelum:

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

Tetapi untuk alasan keamanan mereka merekomendasikan metode berikut

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()}}">
Sajith
sumber
Dokumentasi memberikan saran ini jika seseorang mengikat lebih dari satu ekspresi dalam ng-srcatau src. Sudut 1.2 dan seterusnya, seseorang dapat mengikat hanya satu ekspresi srcdan ng-srcdan sarannya adalah untuk mengambil url dari kode menggunakan fungsi, jika diperlukan.
musically_ut
Tapi saya pikir ada beberapa kesalahan dalam kode Anda. Pengontrol harus seperti ini app.controller ('AppCtrl', function ($ scope) {});
Sajith
1
Pengontrol juga dapat diakses secara global .
musically_ut
Baik. Periksa tautan ini. Saya memeriksa kode Anda dengan plunker. plnkr.co/edit/caqS1jE9fpmMn5NofUve
Sajith
Saya telah memperhatikan fungsi "trustSrc" dalam kode Anda. Harap hapus fungsi itu dan coba lagi seperti ini. {{trustSrc (currentProject.url)}} ke {{currentProject.url}}
Sajith
0

pilih templat; iframe controller, ng pembaruan model

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

Periksa tautan ini: http://plnkr.co/edit/TGRj2o?p=preview

Osman Selvi
sumber
0

Anda juga perlu $sce.trustAsResourceUrlatau itu tidak akan membuka situs web di dalam 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>

Tuan Rumah
sumber