Sumber daya eksternal tidak dimuat oleh AngularJs


195

Menggunakan Angular dan Phonegap, saya mencoba memuat video yang ada di server jarak jauh tetapi menemukan masalah. Di JSON saya, URL dimasukkan sebagai URL HTTP biasa.

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

Template video saya

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

Semua data saya yang lain dimuat tetapi ketika saya melihat konsol saya, saya mendapatkan kesalahan ini:

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

Saya mencoba menambahkan $compileProviderkonfigurasi config saya tetapi tidak menyelesaikan masalah saya.

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

Saya melihat posting ini tentang masalah lintas domain tetapi saya tidak yakin bagaimana menyelesaikan ini atau ke arah mana saya harus masuk. Ada ide? Bantuan apa pun dihargai


1
Bisakah Anda juga memposting config.xmlfile corodva Anda ?
Andrew Shustariov

1
Saat ini saya masih menguji di browser jadi saya bahkan belum memulai debugging phonegap saya.
mhartington

Jawaban:


267

Ini adalah satu-satunya solusi yang bekerja untuk saya:

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

Kemudian di iframe:

<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


Apakah ini mungkin tanpa iFrame? Saya perlu menyematkan video di mana info sesi menentukan apakah konsumen diizinkan melihat video atau tidak. Informasi sesi tidak dibawa melalui iFrame.
Blake

bagus, jika Anda dapat menggunakan iframe
Ringo

270

Solusi sederhana lain adalah membuat filter:

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

Kemudian tentukan filter di ng-src:

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

22
Pasti solusi yang paling elegan dan angulary.
Sc0ttyD

1
Bekerja untuk saya, dan memang lebih bagus daripada menggunakan iframe.
Thomas Amar

1
Jawaban terbaik, lebih banyak semangat sudut dan itu bekerja di mana solusi lain tidak karena beberapa alasan. Terima kasih banyak!
floribon

76

Daftar putih sumber daya dengan $ sceDelegateProvider

Ini disebabkan oleh kebijakan keamanan baru yang diberlakukan di Angular 1.2. Itu membuat XSS lebih sulit dengan mencegah peretas keluar dari panggilan (yaitu membuat permintaan ke URL asing, berpotensi mengandung muatan).

Untuk menyiasatinya dengan benar, Anda perlu memasukkan daftar putih domain yang ingin Anda izinkan, seperti ini:

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

Contoh ini diambil dari dokumentasi yang dapat Anda baca di sini:

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

Pastikan untuk memasukkan ngSanitize dalam aplikasi Anda untuk membuat ini berfungsi.

Menonaktifkan fitur

Jika Anda ingin mematikan fitur yang bermanfaat ini, dan Anda yakin data Anda aman, Anda bisa mengizinkan **, seperti:

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

2
Catatan: jika resourceUrlWhitelistentah bagaimana tidak bekerja untuk Anda, periksa apakah Anda tidak memiliki garis miring ganda setelah nama domain (mudah untuk ini terjadi ketika menggabungkan hal-hal dari variabel dan mereka berdua memiliki garis miring)
jakub.g

2
Ini adalah cara yang lebih bersih, global, dan aman untuk mengatasi masalah ini.
DJ.

"Dialing out" bukan istilah yang bagus untuk digunakan bagi seseorang yang mencoba memahami masalah ini.
Ringo

1
Terima kasih @Ringo - Saya telah menambahkan komentar untuk menjelaskan.
superluminary

21

Punya masalah yang sama di sini. Saya harus mengikat tautan Youtube. Apa yang berhasil bagi saya, sebagai solusi global , adalah menambahkan yang berikut ke konfigurasi saya:

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

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

}]);

Menambahkan 'diri' di sana penting - jika tidak akan gagal mengikat ke URL apa pun. Dari dokumen sudut

'diri' - String khusus, 'diri', dapat digunakan untuk mencocokkan dengan semua URL dari domain yang sama dengan dokumen aplikasi menggunakan protokol yang sama.

Dengan itu, saya sekarang dapat mengikat langsung ke tautan Youtube apa pun.

Anda jelas harus menyesuaikan regex dengan kebutuhan Anda. Semoga ini bisa membantu!


4

Solusi terbaik dan mudah untuk menyelesaikan masalah ini adalah meneruskan data Anda dari fungsi ini di controller.

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

Di halaman html

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

2

Saya mengalami masalah yang sama menggunakan Videogular. Saya mendapatkan yang berikut saat menggunakan ng-src:

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

Saya memperbaiki masalah dengan menulis arahan dasar:

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

Jika ada yang mencari solusi TypeScript:

File .ts (ubah variabel jika berlaku):

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

Berdasarkan pesan kesalahan, masalah Anda tampaknya terkait dengan interpolasi (biasanya ekspresi Anda {{}}), bukan masalah lintas-domain. Pada dasarnya ng-src="{{object.src}}"menyebalkan.

ng-srcdirancang dengan imgtag dalam pikiran IMO. Mungkin tidak cocok untuk <source>. Lihat http://docs.angularjs.org/api/ng.directive:ngSrc

Jika Anda menyatakan <source src="somesite.com/myvideo.mp4"; type="video/mp4"/>, itu akan berfungsi, bukan? (perhatikan bahwa saya menghapus ng-srcmendukung src). Jika tidak harus diperbaiki terlebih dahulu.

Kemudian memastikan bahwa {{object.src}}pengembalian nilai yang diharapkan ( di luar dari <video>):

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

Jika mengembalikan nilai yang diharapkan, pernyataan berikut harus berfungsi:

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

Menggunakan hanya src dan hard coding url, semuanya berfungsi seperti yang saya inginkan. Segera setelah saya menggunakan {{object.src}} meskipun atribut src bahkan tidak lulus. Aku pergi ke depan dan bahkan menghapus tag sumber dan menaruh src inline dengan tag video tapi masih tidak ada
mhartington

Maksud saya, apakah Anda yakin {{object.src}} mengembalikan nilai? Mungkin kembali tidak terdefinisi.
roland

{{object.src}} mengembalikan nilai. Mengujinya dengan menggunakan <p> </p> dan <a> </a>
mhartington

1
Mungkin harus, sudah menemukan ini dan itu terlihat cukup bagus. videogular.com/# . Terima kasih atas bantuannya
mhartington

2
Ini tidak ada hubungannya dengan ng-srcrusak (tidak rusak). Ini berkaitan dengan kebijakan keamanan AngularJS: docs.angularjs.org/api/ng/service/$sce
Pauan

0

Saya memiliki kesalahan ini dalam pengujian , arahan templateUrltidak dipercaya, tetapi hanya untuk spec, jadi saya menambahkan direktori templat:

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

Direktori utama saya adalah app.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.