可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I\'m trying to set the src
attribute of an iframe from a variable and I can\'t get it to work...
The 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>
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 );
}
}
With this code, nothing gets inserted into the iframe\'s src
attribute. It\'s just blank.
Update 1:
I injected the $sce
dependancy into the AppCtrl and $sce.trustUrl() now works without throwing errors. However it returns TrustedValueHolderType
which I\'m not sure how to use to insert an actual URL. The same type is returned whether I use $sce.trustUrl() inside the interpolation braces in the attribute src=\"{{trustUrl(currentProjectUrl))}}\"
or if I do it inside the controller when setting the value of currentProjectUrl. I even tried it with both.
Update 2:
I figured out how to return the url from the trustedUrlHolder using .toString() but when I do that, it throws the security warning when I try to pass it into the src attribute.
Update 3:
It works if I use trustAsResourceUrl() in the controller and pass that to a variable used inside the ng-src attribute:
$scope.setProject = function (id) {
$scope.currentProject = $scope.projects[id];
$scope.currentProjectUrl = $sce.trustAsResourceUrl($scope.currentProject.url);
console.log( $scope.currentProject );
console.log( $scope.currentProjectUrl );
}
My problem seems to be solved by this, although I\'m not quite sure why.
回答1:
I suspect looking at the excerpt that the function trustSrc
from trustSrc(currentProject.url)
is not defined in the controller.
You need to inject the $sce
service in the controller and trustAsResourceUrl
the url
there.
In the controller:
function AppCtrl($scope, $sce) {
// ...
$scope.setProject = function (id) {
$scope.currentProject = $scope.projects[id];
$scope.currentProjectUrl = $sce.trustAsResourceUrl($scope.currentProject.url);
}
}
In the Template:
<iframe ng-src=\"{{currentProjectUrl}}\"> <!--content--> </iframe>
回答2:
It is the $sce service that blocks Urls with external domains, it is a service that provides Strict Contextual Escaping services to AngularJS, to prevent security vulnerabilities such as XSS, clickjacking, etc. it\'s enabled by default in Angular 1.2.
you can disable it completely, but it\'s not recommended
angular.module(\'myAppWithSceDisabledmyApp\', [])
.config(function($sceProvider) {
$sceProvider.enabled(false);
});
for more info
https://docs.angularjs.org/api/ng/service/$sce
回答3:
Please remove call to trustSrc
function and try again like this . {{trustSrc(currentProject.url)}} to {{currentProject.url}}.
Check this link http://plnkr.co/edit/caqS1jE9fpmMn5NofUve?p=preview
But according to the Angular Js 1.2 Documentation, you should write a function for getting
src
url. Have a look on the following code.
Before:
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}}\"
But for security reason they are recommending following method
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()}}\">
回答4:
this way i follow and its work for me fine, may it will works for you,
<iframe class=\"img-responsive\" src=\"{{pdfLoc| trustThisUrl }}\" ng-style=\"{
height: iframeHeight * 0.75 + \'px\'
}\" style=\"width:100%\"></iframe>
here trustThisUrl is just filter,
angular.module(\"app\").filter(\'trustThisUrl\', [\"$sce\", function ($sce) {
return function (val) {
return $sce.trustAsResourceUrl(val);
};
}]);
回答5:
select template;
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];
});
};
Check this link: http://plnkr.co/edit/TGRj2o?p=preview
回答6:
You need also $sce.trustAsResourceUrl
or it won\'t open the website inside the 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>