J'essaie de définir l'attribut src
d'une iframe à partir d'une variable et je n'arrive 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'attribut src
de l'iframe. C'est juste vide.
Mise à jour 1: J'ai injecté la dépendance $sce
dans AppCtrl et $ sce.trustUrl () fonctionne désormais sans erreur. Cependant, il retourne TrustedValueHolderType
que je ne sais pas comment utiliser pour insérer une URL réelle. Le même type est renvoyé si j'utilise $ sce.trustUrl () dans les accolades d'interpolation de l'attribut src="{{trustUrl(currentProjectUrl))}}"
ou si je le fais dans le 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 découvert comment renvoyer l'URL de trustedUrlHolder à l'aide de .toString (), mais lorsque je le fais, il envoie l'avertissement de sécurité lorsque je tente de le transmettre dans l'attribut src.
Mise à jour 3: Cela fonctionne si j'utilise trustAsResourceUrl () dans le contrôleur et que je le passe à une variable utilisée dans l'attribut 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 );
}
Mon problème semble être résolu par ceci, bien que je ne sois pas tout à fait pourquoi.
Je suspecte de regarder dans l'extrait que la fonction trustSrc
de trustSrc(currentProject.url)
n'est pas définie dans le contrôleur.
Vous devez injecter le $sce
service dans le contrôleur et trustAsResourceUrl
la 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}}"> <!--content--> </iframe>
C’est le service $ sce qui bloque les URL avec les domaines externes, c’est un service qui fournit des services d’échappement contextuel strict à AngularJS, afin de prévenir les failles de sécurité telles que XSS, le détournement de clics, 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
Veuillez supprimer l'appel à la fonction trustSrc
et réessayer comme ceci. {{trustSrc (currentProject.url)}} à {{currentProject.url}} . Vérifiez ce lien http://plnkr.co/edit/caqS1jE9fpmMn5NofUve?p=preview
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()}}">
de cette façon, je suis et son travail pour moi va bien, que ça marche 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);
};
}]);
Vous devez également utiliser $sce.trustAsResourceUrl
ou le site Web à l'intérieur de l'iframe ne sera pas ouvert:
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>
sélectionner un modèle; contrôleur iframe, mise à jour du modèle
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