web-dev-qa-db-ja.com

AngularJSの変数からiframe src属性を設定する方法

変数からiframeのsrc属性を設定しようとしていますが、動作させることができません...

マークアップ:

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

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

    }
}

このコードでは、iframeのsrc属性には何も挿入されません。ただ空白です。

更新1: / AppCtrlに$sce依存関係を挿入し、$ sce.trustUrl()はエラーをスローせずに動作するようになりました。しかし、それはTrustedValueHolderTypeを返します。これは実際のURLを挿入するための使い方がわかりません。属性src="{{trustUrl(currentProjectUrl))}}"の補間括弧内で$ sce.trustUrl()を使用しても、currentProjectUrlの値を設定するときにコントローラー内で使用しても、同じ型が返されます。私も両方で試しました。

更新2: / .toString()を使用してtrustedUrlHolderからURLを返す方法を考え出しましたが、それを行うと、src属性に渡すとセキュリティ警告がスローされます。

Update 3: /コントローラでtrustAsResourceUrl()を使用し、それを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 );

}

私の問題はこれで解決されるようですが、理由はよくわかりません。

206
emersonthis

trustSrc(currentProject.url)からの関数trustSrcがコントローラで定義されていないという抜粋を見ているのではないかと思います。

コントローラに $sceサービス を注入し、そこでtrustAsResourceUrlurlに注入する必要があります。

コントローラで:

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

テンプレート内:

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

外部ドメインでURLをブロックするのは$ sceサービスで、XSS、クリックジャックなどのセキュリティの脆弱性を防ぐためにAngularJSにStrict Contextual Escapingサービスを提供するサービスです。Angularでデフォルトで有効になっています。 1.2。

完全に無効にすることはできますが、お勧めできません

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

詳細については https://docs.angularjs.org/api/ng/service/ $ sce

11
Mohamed Selim

このように私が従って、私のためにその仕事はうまくいく、それはあなたのために働くだろう、

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

ここでtrustThisUrlは単なるフィルタです、

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

$sce.trustAsResourceUrlも必要です。そうしないと、iframe内でWebサイトを開くことができません。

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>
0
Abdo-Host

テンプレートを選択してください。 iframeコントローラ、モデルアップデート

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

このリンクをチェックしてください: http://plnkr.co/edit/TGRj2o?p=preview

0
Osman Selvi