Внешний ресурс, не загружаемый AngularJs
Используя Angular и Phonegap, я пытаюсь загрузить видео, которое находится на удаленном сервере, но столкнулось с проблемой. В моем JSON URL-адрес вводится как простой URL-адрес HTTP.
"src" : "http://www.somesite.com/myvideo.mp4"
Мой шаблон видео
<video controls poster="img/poster.png">
<source ng-src="{{object.src}}" type="video/mp4"/>
</video>
Все мои другие данные загружаются, но когда я смотрю на свою консоль, я получаю эту ошибку:
Error: [$interpolate:interr] Can't interpolate: {{object.src}}
Error: [$sce:insecurl] Blocked loading resource from url not allowed by $sceDelegate policy. URL
Я попытался добавить $compileProvider
в мою конфигурацию, но это не решило мою проблему.
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel):/);
Я видел эту статью о проблеме с перекрестным доменом, но я не уверен, как решить это или какое направление мне нужно. Есть идеи? Любая помощь приветствуется
Ответы
Ответ 1
Это единственное решение, которое сработало для меня:
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"};
});
Затем в iframe:
<iframe class="youtube-player" type="text/html" width="640" height="385" ng-src="{{trustSrc(movie.src)}}" allowfullscreen frameborder="0">
http://plnkr.co/edit/tYq22VjwB10WmytQO9Pb?p=preview
Ответ 2
Другим простым решением является создание фильтра:
app.filter('trusted', ['$sce', function ($sce) {
return function(url) {
return $sce.trustAsResourceUrl(url);
};
}]);
Затем укажите фильтр в ng-src
:
<video controls poster="img/poster.png">
<source ng-src="{{object.src | trusted}}" type="video/mp4"/>
</video>
Ответ 3
Белый список ресурсов с помощью $sceDelegateProvider
Это вызвано новой политикой безопасности, установленной в Angular 1.2. Это упрощает XSS, не позволяя хакеру набирать номер (т.е. Делая запрос на внешний URL-адрес, потенциально содержащий полезную нагрузку).
Чтобы обойти это правильно, вам нужно переименовать домены, которые вы хотите разрешить, например:
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**'
]);
});
Этот пример снят с документации, которую вы можете прочитать здесь:
https://docs.angularjs.org/api/ng/provider/$sceDelegateProvider
Обязательно включите ngSanitize в ваше приложение, чтобы сделать эту работу.
Отключение функции
Если вы хотите отключить эту полезную функцию, и вы уверены, что ваши данные защищены, вы можете просто разрешить **, например:
angular.module('app').config(function($sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhitelist(['**']);
});
Ответ 4
Здесь была такая же проблема. Мне нужно было привязать ссылки Youtube. Что для меня работало, так как глобальное решение заключалось в добавлении следующего в мою конфигурацию:
.config(['$routeProvider', '$sceDelegateProvider',
function ($routeProvider, $sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhitelist(['self', new RegExp('^(http[s]?):\/\/(w{3}.)?youtube\.com/.+$')]);
}]);
Добавление 'self' там важно, иначе не будет привязываться к любому URL-адресу. Из angular docs
'self' - специальная строка, "self", может использоваться для сопоставления со всеми URL-адреса того же домена, что и документ приложения, с использованием того же Протокол.
С этим я теперь могу привязываться напрямую к любой ссылке Youtube.
Очевидно, вам придется настраивать регулярное выражение в соответствии с вашими потребностями. Надеюсь, это поможет!
Ответ 5
Лучшим и легким решением для решения этой проблемы является передача ваших данных из этой функции в контроллер.
$scope.trustSrcurl = function(data)
{
return $sce.trustAsResourceUrl(data);
}
В html странице
<iframe class="youtube-player" type="text/html" width="640" height="385" ng-src="{{trustSrcurl(video.src)}}" allowfullscreen frameborder="0"></iframe>
Ответ 6
Я столкнулся с той же проблемой, используя Videogular. При использовании ng-src я получал следующее:
Error: [$interpolate:interr] Can't interpolate: {{url}}
Error: [$sce:insecurl] Blocked loading resource from url not allowed by $sceDelegate policy
Я исправил проблему, написав базовую директиву:
angular.module('app').directive('dynamicUrl', function () {
return {
restrict: 'A',
link: function postLink(scope, element, attrs) {
element.attr('src', scope.content.fullUrl);
}
};
});
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>
Ответ 7
Если кто-то ищет решение TypeScript:
.ts файл (при необходимости изменяйте переменные):
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>
Ответ 8
Основываясь на сообщении об ошибке, ваша проблема, похоже, связана с интерполяцией (как правило, с выражением {{}}
), а не с междоменной проблемой. В основном ng-src="{{object.src}}"
отстой.
ng-src
был разработан с тегом img
в виду IMO. Возможно, это не подходит для <source>
. См. http://docs.angularjs.org/api/ng.directive:ngSrc
Если вы объявите <source src="somesite.com/myvideo.mp4"; type="video/mp4"/>
, он будет работать, правильно? (обратите внимание, что я удаляю ng-src
в пользу src
). Если он не должен быть исправлен первым.
Затем убедитесь, что {{object.src}}
возвращает ожидаемое значение ( вне <video>
):
<span>{{object.src}}</span>
<video>...</video>
Если он возвращает ожидаемое значение, должен работать следующий оператор:
<source src="{{object.src}}"; type="video/mp4"/> //src instead of ng-src