219 votes

JS angulaire : Comment définir un attribut d’iframe src d’une variable

Je suis en train de régler le src d'attribut d'un iframe à partir d'une variable et je ne peux pas le faire fonctionner...

Le balisage:

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

    }
}

Avec ce code, rien n'est inséré dans l'iframe de l' src d'attribut. C'est juste vide.

Mise à jour 1: J'ai injecté le $sce de dépendance dans le AppCtrl et $sce.trustUrl() fonctionne maintenant sans provoquer des erreurs. Toutefois, il retourne TrustedValueHolderType dont je ne suis pas sûr de la façon de les utiliser pour insérer une URL réelle. Le même type est retourné si j'utilise $sce.trustUrl() à l'intérieur de l'interpolation des accolades dans l'attribut src="{{trustUrl(currentProjectUrl))}}" ou si je le fais à l'intérieur du contrôleur lors de la définition de la valeur de currentProjectUrl. J'ai même essayé avec les deux.

Mise à jour 2: J'ai trouvé comment afficher l'url de la trustedUrlHolder à l'aide .toString() mais lorsque je fais cela, il lance l'avertissement de sécurité lorsque j'essaie de la passer dans l'attribut src.

Mise à jour 3: Il fonctionne si j'utilise trustAsResourceUrl() dans le contrôleur et le passer à une variable utilisée à l'intérieur de la ng-attribut 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 );

}

Mon problème semble être résolu par la présente, bien que je ne suis pas tout à fait sûr pourquoi.

370voto

musically_ut Points 13260

Je soupçonne en regardant l'extrait que la fonction trustSrc de trustSrc(currentProject.url) n'est pas définie dans le contrôleur.

Vous avez besoin d'injecter de l' $sce service dans le contrôleur et l' trustAsResourceUrl le url .

Dans le contrôleur:

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

Dans le Modèle:

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

1 votes

J'ai essayé avec $sce comme vous l'avez recommandé. Le message d'erreur disparaît, mais l'attribut src de l'iframe reste vide.

4 votes

Essayez d'utiliser trustAsResourceUrl .

0 votes

TrustAsResourceUrl semble retourner le même objet que trustAsUrl()

10voto

Mohamed Selim Points 1522

C'est le $sce service qui bloque les URL avec des domaines externes, c'est un service qui fournit des services d'échappement contextuel strict à AngularJS, afin de prévenir les vulnérabilités de sécurité telles que XSS, clickjacking, etc. Il est activé par défaut dans Angular 1.2.

Vous pouvez le désactiver complètement, mais ce n'est pas recommandé.

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

pour plus d'informations https://docs.angularjs.org/api/ng/service/$sce

5voto

chandrakant Points 285

Je suis cette méthode et elle fonctionne bien pour moi, elle fonctionnera peut-être pour vous,

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

ici trustThisUrl est juste un filtre,

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

2voto

Sajith Points 834

Veuillez retirer l'appel à trustSrc et réessayez comme suit : {{trustSrc(currentProject.url)}} à {{currentProject.url}}. Vérifiez ce lien http://plnkr.co/edit/caqS1jE9fpmMn5NofUve?p=preview


Mais selon la documentation Angular Js 1.2, vous devriez écrire une fonction pour obtenir src url. Regardez le code suivant.

Avant :

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

Mais pour des raisons de sécurité, ils recommandent la méthode suivante

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

0 votes

La documentation fournit ce conseil dans le cas où l'on se lie à plus d'une expression dans le fichier ng-src o src . À partir de la version 1.2 d'Angular, on ne peut se lier qu'à une seule expression dans la section src y ng-src et le conseil est de récupérer une url à partir du code en utilisant une fonction, si nécessaire.

0 votes

Mais je pense qu'il y a une erreur dans votre code. Le contrôleur devrait être comme ceci app.controller('AppCtrl', function($scope) {}) ;

1 votes

Les contrôleurs peuvent être Fonctions accessibles à tous également.

0voto

Osman Selvi Points 31

Sélectionnez le modèle ; contrôleur iframe, mise à jour du modèle 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];
        });
    };

Vérifiez ce lien : http://plnkr.co/edit/TGRj2o?p=preview

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X