Внешний ресурс не загружается AngularJs

используя Angular и Phonegap, я пытаюсь загрузить видео, которое находится на удаленном сервере, но столкнулся с проблемой. В моем JSON URL-адрес вводится как простой HTTP-URL.

"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):/);

Я видел это сообщение о междоменная проблемаs но я не уверен, как решить это или в каком направлении я должен идти. Есть идеи? Любая помощь приветствуется

9 ответов


это единственное решение, которое работает для меня:

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


еще одно простое решение-создать фильтр:

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>

белый список ресурса с $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(['**']);
});

здесь была та же проблема. Мне нужно было привязаться к ссылкам Youtube. Что сработало для меня, как глобальное решение, должен был добавить следующее в мою конфигурацию:

.config(['$routeProvider', '$sceDelegateProvider',
        function ($routeProvider, $sceDelegateProvider) {

    $sceDelegateProvider.resourceUrlWhitelist(['self', new RegExp('^(http[s]?):\/\/(w{3}.)?youtube\.com/.+$')]);

}]);

добавлять 'self' там важно-в противном случае не удастся привязать к любому URL. От угловое документы

'self' - специальная строка "self" может использоваться для сопоставления со всеми URL-адреса того же домена, что и документ приложения, используя тот же протокол.

С этим на месте, я теперь могу привязаться непосредственно к любой ссылке Youtube.

Вам, очевидно, придется настроить регулярное выражение для ваших нужд. Надеюсь, это поможет!


лучшим и простым решением для решения этой проблемы является передача данных из этой функции в контроллер.

$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>

я столкнулся с той же проблемой, используя 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>

Если кто-то ищет решение 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>

основываясь на сообщении об ошибке, ваша проблема, похоже, связана с интерполяция (как правило, ваше выражение {{}}), а не кросс-доменных вопрос. В основном ng-src="{{object.src}}" хреново.

ng-src был разработан с img тег в виду ММО. Это может быть не подходит для <source>. См.http://docs.angularjs.org/api/ng.directive:ngSrc

если вы объявляете <source src="somesite.com/myvideo.mp4"; type="video/mp4"/>, это будет работать, не так ли? (обратите внимание, что я удаляю ng-src в пользу src) если это не должно быть исправлено в первую очередь.

убедитесь, что {{object.src}} возвращает ожидаемое значение (за пределами of <video>):

<span>{{object.src}}</span>
<video>...</video>

если он возвращает ожидаемое значение, должен работать следующий оператор:

<source src="{{object.src}}"; type="video/mp4"/> //src instead of ng-src

у меня была эта ошибка в тесты, директивой templateUrl не был доверенным, но только для спецификации, поэтому я добавил каталог шаблонов:

beforeEach(angular.mock.module('app.templates'));

мой основной каталог -app.