Внешний ресурс, не загружаемый 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