So legen Sie ein iframe src-Attribut aus einer Variablen in AngularJS fest

214

Ich versuche, das srcAttribut eines Iframes aus einer Variablen festzulegen, und ich kann es nicht zum Laufen bringen ...

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

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

    }
}

Mit diesem Code wird nichts in das srcAttribut des Iframes eingefügt . Es ist nur leer.

Update 1: Ich habe $scedie Abhängigkeit in AppCtrl eingefügt und $ sce.trustUrl () funktioniert jetzt ohne Fehler. Es wird jedoch zurückgegeben, TrustedValueHolderTypewas ich nicht sicher bin, wie ich eine tatsächliche URL einfügen soll. Der gleiche Typ wird zurückgegeben, unabhängig davon, ob ich $ sce.trustUrl () in den Interpolationsklammern im Attribut verwende src="{{trustUrl(currentProjectUrl))}}"oder ob ich dies innerhalb des Controllers mache, wenn ich den Wert von currentProjectUrl setze. Ich habe es sogar mit beiden versucht.

Update 2: Ich habe herausgefunden, wie die URL mit .toString () vom TrustedUrlHolder zurückgegeben werden kann. Dabei wird jedoch die Sicherheitswarnung ausgegeben, wenn ich versuche, sie an das src-Attribut zu übergeben.

Update 3: Es funktioniert, wenn ich trustAsResourceUrl () im Controller verwende und dies an eine Variable übergebe, die im Attribut ng-src verwendet wird:

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

}

Mein Problem scheint dadurch gelöst zu sein, obwohl ich nicht ganz sicher bin, warum.

emersonthis
quelle

Antworten:

359

Ich vermute im Blick auf den Auszug, dass die Funktion trustSrcvon trustSrc(currentProject.url)nicht in der Steuerung definiert ist.

Sie müssen den $sceDienst in die Steuerung und trustAsResourceUrldie einspeisenurl dort.

In der Steuerung:

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

In der Vorlage:

<iframe ng-src="{{currentProjectUrl}}"> <!--content--> </iframe>
musikalisch_ut
quelle
1
Ich habe es mit $ sce versucht, wie Sie empfohlen haben. Die Fehlermeldung wird ausgeblendet, aber das src-Attribut des iframe ist immer noch leer.
Emersonthis
3
Versuchen Sie es mit trustAsResourceUrl.
musikalisch_ut
9
... aber dieser funktioniert, wenn ich ihn an das Attribut ng-src übergebe! Vielen Dank.
Emersonthis
2
@Emerson trustAsResourceUrlgibt eine zurück, $sce.RESOURCE_URLdie für iframe/ objectswhile benötigt wird, und trustAsUrlgibt eine zurück, $sce.URLdie eine schwächere Art von Garantie darstellt (und derzeit gemäß Dokumentation nicht verwendet wird ).
musikalisch_ut
1
ng-src funktionierte nicht für mich, es sei denn, ich entfernte die doppelten geschweiften Klammern (ng-src = "currentProjectUrl")
baacke
10

Es ist der $sce Dienst, der URLs mit externen Domänen blockiert. Es ist ein Dienst, der AngularJS Strict Contextual Escaping-Dienste bereitstellt, um Sicherheitslücken wie XSS, Clickjacking usw. zu verhindern. Er ist in Angular 1.2 standardmäßig aktiviert.

Sie können es vollständig deaktivieren, es wird jedoch nicht empfohlen

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

Weitere Informationen finden Sie unter https://docs.angularjs.org/api/ng/service/$sce

Mohamed Selim
quelle
3

auf diese Weise folge ich und seine Arbeit für mich gut, möge es für Sie funktionieren,

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

hier trustThisUrl ist nur Filter,

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

Bitte entfernen Sie den trustSrcFunktionsaufruf und versuchen Sie es erneut. {{trustSrc (currentProject.url)}} bis {{currentProject.url}}. Überprüfen Sie diesen Link http://plnkr.co/edit/caqS1jE9fpmMn5NofUve?p=preview


Gemäß der Angular Js 1.2-Dokumentation sollten Sie jedoch eine Funktion zum Abrufen der srcURL schreiben . Schauen Sie sich den folgenden Code an.

Vor:

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

Aus Sicherheitsgründen empfehlen sie jedoch die folgende Methode

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
quelle
Die Dokumentation bietet diesen Rat für den Fall, dass einer an mehr als einen Ausdruck in ng-srcoder gebunden ist src. Angular 1.2 ab, kann man nur mit einem Ausdruck binden in srcund ng-srcund die Beratung ist eine URL aus dem Code unter Verwendung einer Funktion abrufen, wenn nötig.
musikalisch_ut
Aber ich denke, es gibt einen Fehler in Ihrem Code. Der Controller sollte wie folgt aussehen: app.controller ('AppCtrl', Funktion ($ scope) {});
Sajith
1
Controller können auch global zugängliche Funktionen sein .
musikalisch_ut
OK. Überprüfen Sie diesen Link Ich habe Ihren Code mit Plunker überprüft. plnkr.co/edit/caqS1jE9fpmMn5NofUve
Sajith
Ich habe eine Funktion "trustSrc" in Ihrem Code bemerkt. Bitte entfernen Sie diese Funktion und versuchen Sie es erneut. {{trustSrc (currentProject.url)}} bis {{currentProject.url}}
Sajith
0

Vorlage auswählen; iframe controller, ng model update

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

Überprüfen Sie diesen Link: http://plnkr.co/edit/TGRj2o?p=preview

Osman Selvi
quelle
0

Sie benötigen auch $sce.trustAsResourceUrloder es wird nicht die Website innerhalb des Iframes öffnen:

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>

Abdo-Host
quelle