Ressource externe non chargée par AngularJs
en utilisant Angular et Phonegap, j'essaye de charger une vidéo qui est sur un serveur distant mais qui a rencontré un problème. Dans mon JSON, L'URL est entrée comme une URL HTTP simple.
"src" : "http://www.somesite.com/myvideo.mp4"
mon modèle vidéo
<video controls poster="img/poster.png">
<source ng-src="{{object.src}}" type="video/mp4"/>
</video>
toutes mes autres données sont chargées mais quand je regarde ma console, je reçois cette erreur:
Error: [$interpolate:interr] Can't interpolate: {{object.src}}
Error: [$sce:insecurl] Blocked loading resource from url not allowed by $sceDelegate policy. URL
j'ai essayé en ajoutant $compileProvider
dans ma config, mais cela n'a pas résolu mon problème.
$compileProvider.aHrefSanitizationWhitelist(/^s*(https?|ftp|mailto|file|tel):/);
j'ai vu ce post sur la question de domaine croisé s mais je ne sais pas comment résoudre ce ou quelle direction je devrais aller. Des idées? Toute aide est appréciée
9 réponses
C'est la seule solution qui a fonctionné pour moi:
var app = angular.module('plunker', ['ngSanitize']);
app.controller('MainCtrl', function($scope, $sce) {
$scope.trustSrc = function(src) {
return $sce.trustAsResourceUrl(src);
}
$scope.movie = {src:"http://www.youtube.com/embed/Lx7ycjC8qjE", title:"Egghead.io AngularJS Binding"};
});
puis dans une iframe:
<iframe class="youtube-player" type="text/html" width="640" height="385" ng-src="{{trustSrc(movie.src)}}" allowfullscreen frameborder="0">
une autre solution simple est de créer un filtre:
app.filter('trusted', ['$sce', function ($sce) {
return function(url) {
return $sce.trustAsResourceUrl(url);
};
}]);
alors spécifier le filtre dans ng-src
:
<video controls poster="img/poster.png">
<source ng-src="{{object.src | trusted}}" type="video/mp4"/>
</video>
liste Blanche de la ressource avec $sceDelegateProvider
ceci est causé par une nouvelle politique de sécurité mise en place dans L'angle 1.2. Il rend XSS plus difficile en empêchant un hacker de composer (c.-à-d. faire une demande à une URL étrangère, contenant potentiellement une charge utile).
pour le contourner correctement, vous devez whitelist les domaines que vous voulez autoriser, comme ceci:
angular.module('myApp',['ngSanitize']).config(function($sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhitelist([
// Allow same origin resource loads.
'self',
// Allow loading from our assets domain. Notice the difference between * and **.
'http://srv*.assets.example.com/**'
]);
// The blacklist overrides the whitelist so the open redirect here is blocked.
$sceDelegateProvider.resourceUrlBlacklist([
'http://myapp.example.com/clickThru**'
]);
});
cet exemple est tiré du documentation que vous pouvez lire ici:
https://docs.angularjs.org/api/ng/provider / $ sceDelegateProvider
assurez-vous d'inclure ngSanitize dans votre application pour faire ce travail.
désactiver la fonctionnalité
si vous voulez désactiver cette fonctionnalité utile, et que vous êtes sûr que vos données sont sécurisées, vous pouvez simplement autoriser**, comme ceci:
angular.module('app').config(function($sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhitelist(['**']);
});
avait le même problème ici. J'avais besoin de me lier à des liens Youtube. Ce qui a fonctionné pour moi, comme une solution globale , était d'ajouter ce qui suit à ma config:
.config(['$routeProvider', '$sceDelegateProvider',
function ($routeProvider, $sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhitelist(['self', new RegExp('^(http[s]?):\/\/(w{3}.)?youtube\.com/.+$')]);
}]);
ajouter ' self ' dans Il est important - sinon ne se liera à aucune URL. De la documents angulaires
'self' - la chaîne spéciale, 'self', peut être utilisée pour correspondre à tous URL du même domaine que le document de demande en utilisant le même protocole.
avec cela en place, je suis maintenant en mesure de lier directement à n'importe quel lien Youtube.
il va de soi que vous devrez adapter le regex à vos besoins. Espérons que cela aide!
la meilleure et la solution facile pour résoudre ce problème est de passer vos données de cette fonction dans le contrôleur.
$scope.trustSrcurl = function(data)
{
return $sce.trustAsResourceUrl(data);
}
en page html
<iframe class="youtube-player" type="text/html" width="640" height="385" ng-src="{{trustSrcurl(video.src)}}" allowfullscreen frameborder="0"></iframe>
j'ai rencontré le même problème en utilisant Videogular. J'ai eu ce qui suit en utilisant ng-src:
Error: [$interpolate:interr] Can't interpolate: {{url}}
Error: [$sce:insecurl] Blocked loading resource from url not allowed by $sceDelegate policy
j'ai corrigé le problème en écrivant une directive de base:
angular.module('app').directive('dynamicUrl', function () {
return {
restrict: 'A',
link: function postLink(scope, element, attrs) {
element.attr('src', scope.content.fullUrl);
}
};
});
Le code html:
<div videogular vg-width="200" vg-height="300" vg-theme="config.theme">
<video class='videoPlayer' controls preload='none'>
<source dynamic-url src='' type='{{ content.mimeType }}'>
</video>
</div>
si quelqu'un cherche une solution dactylographiée:
.fichier ts (changer les variables le cas échéant):
module App.Filters {
export class trustedResource {
static $inject:string[] = ['$sce'];
static filter($sce:ng.ISCEService) {
return (value) => {
return $sce.trustAsResourceUrl(value)
};
}
}
}
filters.filter('trustedResource', App.Filters.trusted.filter);
Html:
<video controls ng-if="HeaderVideoUrl != null">
<source ng-src="{{HeaderVideoUrl | trustedResource}}" type="video/mp4"/>
</video>
basé sur le message d'erreur, votre problème semble être lié à interpolation (typiquement votre expression {{}}
), pas à un problème transversal. En gros, ng-src="{{object.src}}"
craint.
ng-src
a été conçu avec img
étiquette à L'esprit IMO. Il pourrait ne pas être approprié pour <source>
. Voir http://docs.angularjs.org/api/ng.directive:ngSrc
si vous déclarez <source src="somesite.com/myvideo.mp4"; type="video/mp4"/>
, ça va marcher, non? (notez que je supprime ng-src
en faveur de src
) sinon, il doit être fixé en premier.
s'assurer ensuite que {{object.src}}
renvoie la valeur attendue ( en dehors de de <video>
):
<span>{{object.src}}</span>
<video>...</video>
si elle renvoie la valeur attendue, l'énoncé suivant devrait fonctionner:
<source src="{{object.src}}"; type="video/mp4"/> //src instead of ng-src
j'ai eu cette erreur dans tests , la directive templateUrl
n'était pas fiable, mais seulement pour les spécifications, donc j'ai ajouté le répertoire de modèle:
beforeEach(angular.mock.module('app.templates'));
Mon répertoire principal est app
.