Dış kaynak AngularJ'ler tarafından yüklenmiyor


195

Angular ve Phonegap kullanarak, uzak bir sunucuda bulunan ancak bir sorunla karşılaşan bir video yüklemeye çalışıyorum. JSON'umda URL, düz HTTP URL olarak girildi.

"src" : "http://www.somesite.com/myvideo.mp4"

Video şablonum

 <video controls poster="img/poster.png">
       <source ng-src="{{object.src}}" type="video/mp4"/>
 </video>

Diğer tüm verilerim yüklenir ancak konsoluma baktığımda şu hatayı alıyorum:

Error: [$interpolate:interr] Can't interpolate: {{object.src}}
Error: [$sce:insecurl] Blocked loading resource from url not allowed by $sceDelegate policy.  URL

$compileProviderYapılandırma ayarımı eklemeyi denedim ancak sorunumu çözmedi.

$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel):/);

Alanlar arası sorunlar hakkında bu gönderiyi gördüm, ancak bunu nasıl çözeceğimi veya hangi yöne gireceğimi bilmiyorum. Herhangi bir fikir? Herhangi bir yardım takdir edilir


1
Ayrıca corodva'nızın config.xmldosyasını da gönderebilir misiniz ?
Andrew Shustariov

1
Şu anda hala tarayıcıda test ediyorum, bu yüzden telefon boşluğumda hata ayıklamaya bile başlamadım.
mhartington

Yanıtlar:


267

Benim için işe yarayan tek çözüm bu:

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"};
});

Sonra bir iframe içinde:

<iframe class="youtube-player" type="text/html" width="640" height="385"
        ng-src="{{trustSrc(movie.src)}}" allowfullscreen frameborder="0">
</iframe>

http://plnkr.co/edit/tYq22VjwB10WmytQO9Pb?p=preview


İFrame olmadan bu mümkün müdür? Oturum bilgisi tüketicinin videoyu görmesine izin verilip verilmediğini belirleyen bir video yerleştirmek zorundayım. Oturum bilgileri iFrame aracılığıyla taşınmaz.
Blake

iframe kullanabiliyorsanız güzel
Ringo

270

Başka bir basit çözüm bir filtre oluşturmaktır:

app.filter('trusted', ['$sce', function ($sce) {
    return function(url) {
        return $sce.trustAsResourceUrl(url);
    };
}]);

Ardından filtreyi şurada belirtin ng-src:

<video controls poster="img/poster.png">
       <source ng-src="{{object.src | trusted}}" type="video/mp4"/>
</video>

22
Kesinlikle en zarif ve açısal çözüm.
Sc0ttyD

1
Benim için çalıştı ve gerçekten bir iframe kullanmaktan daha güzel.
Thomas Amar

1
En iyi cevap, daha açısal bir ruh ve diğer çözümlerin bazı nedenlerden ötürü olmadığı yerde çalıştı. Çok teşekkürler!
floribon

76

$ SceDelegateProvider ile kaynağı beyaz listeye ekleyin

Bu, Açısal 1.2'de uygulamaya konan yeni bir güvenlik politikasından kaynaklanmaktadır. Bir hacker'ın dışarı arama yapmasını engelleyerek XSS'yi zorlaştırır (örneğin, potansiyel olarak bir yük içeren, yabancı bir URL'ye istekte bulunur).

Düzgün bir şekilde dolaşmak için izin vermek istediğiniz alan adlarını beyaz listeye eklemeniz gerekir, örneğin:

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**'
  ]);
});

Bu örnek, buradan okuyabileceğiniz belgelerden kaldırılmıştır:

https://docs.angularjs.org/api/ng/provider/$sceDelegateProvider

Bu çalışmayı yapmak için ngSanitize uygulamasını eklediğinizden emin olun.

Özelliği devre dışı bırakma

Bu kullanışlı özelliği kapatmak istiyorsanız ve verilerinizin güvenli olduğundan eminseniz, ** öğesine izin verebilirsiniz, örneğin:

angular.module('app').config(function($sceDelegateProvider) {
  $sceDelegateProvider.resourceUrlWhitelist(['**']);
});

2
Not: bir resourceUrlWhitelistşekilde sizin için işe yaramazsa, alan adından sonra çift eğik çizgi olup olmadığını kontrol edin (değişkenlerden bir şeyleri birleştirirken bunun kolay olması ve her ikisinin de eğik çizgileri varsa)
jakub.g

2
Bu, bu sorunu çözmenin daha temiz, küresel ve güvenli bir yoludur.
DJ.

"Dışarı arama" sorunu anlamaya çalışan biri için harika bir terim değildir.
Ringo

1
Teşekkürler @Ringo - Açıklığa kavuşturmak için bir yorum ekledim.
superluminary

21

Burada da aynı sorun vardı. Youtube bağlantılarına bağlanmam gerekiyordu. Küresel bir çözüm olarak benim için işe yarayan şey, yapılandırmamıza aşağıdakileri eklemekti:

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

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

}]);

Oraya 'benlik' eklemek önemlidir - aksi takdirde herhangi bir URL'ye bağlanamaz. Gönderen açısal docs

'self' - 'self' özel dizesi, aynı protokolü kullanarak uygulama belgesiyle aynı etki alanının tüm URL'leriyle eşleşmek için kullanılabilir.

Bu durumda, artık doğrudan herhangi bir Youtube bağlantısına bağlanabiliyorum.

Açıkça, normal ifadeyi ihtiyaçlarınıza göre özelleştirmeniz gerekecek. Umarım yardımcı olur!


4

Bu sorunu çözmek için en iyi ve kolay çözüm, verilerinizi denetleyicideki bu işlevden geçirmektir.

$scope.trustSrcurl = function(data) 
{
    return $sce.trustAsResourceUrl(data);
}

Html sayfasında

<iframe class="youtube-player" type="text/html" width="640" height="385" ng-src="{{trustSrcurl(video.src)}}" allowfullscreen frameborder="0"></iframe>

2

Aynı problemi Videogular kullanarak karşılaştım. Ng-src kullanırken aşağıdakileri alıyordum:

Error: [$interpolate:interr] Can't interpolate: {{url}}
Error: [$sce:insecurl] Blocked loading resource from url not allowed by $sceDelegate policy

Temel bir yönerge yazarak sorunu çözdüm:

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>

2

Birisi bir TypeScript çözümü arıyorsa:

.ts dosyası (varsa değişkenleri değiştirin):

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>

1

Hata iletisine dayanarak, sorununuz etki alanları arası bir sorunla değil enterpolasyonla (genellikle ifadenizle {{}}) ilgili gibi görünmektedir . Temelde ng-src="{{object.src}}"berbat.

ng-srcimgIMO etiketi düşünülerek tasarlanmıştır . İçin uygun olmayabilir <source>. Bkz. Http://docs.angularjs.org/api/ng.directive:ngSrc

Bildirirseniz <source src="somesite.com/myvideo.mp4"; type="video/mp4"/>, işe yarayacak, değil mi? ( ng-srclehine kaldırıyorum unutmayın src) Değilse önce düzeltilmesi gerekir.

Sonra sağlamak {{object.src}}döndürür beklenen değeri ( dış ait <video>):

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

Beklenen değeri döndürürse, aşağıdaki ifade çalışıyor olmalıdır:

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

Sadece src ve url kodlama kullanarak, her şey istediğim gibi çalışır. {{Object.src}} 'i kullandığım anda src niteliği düşünceden bile geçmedi. Ben devam etti ve hatta kaynak etiketi kaldırmak ve src video etiketi ile satır içi ama yine de hiçbir şey koymak
mhartington

{{Object.src}} bir değer döndürdüğünden emin misiniz? Tanımsız olarak dönebilir.
roland

{{object.src}} bir değer döndürüyor. Bir <p> </p> ve bir <a> </a> kullanarak test edildi
mhartington

1
Muhtemelen gerekecek, bunu zaten buldu ve oldukça iyi görünüyor. videogular.com/# . Yardım için teşekkürler
mhartington

2
Bunun ng-srckırılmayla ilgisi yoktur (kırılmaz). AngularJS'nin güvenlik politikası ile ilgisi vardır: docs.angularjs.org/api/ng/service/$sce
Pauan

0

Testlerde bu hatayı aldım , direktif templateUrlgüvenilir değildi, ama sadece spec için, bu yüzden şablon dizinini ekledim:

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

Ana dizinim app.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.