14

I am trying to use angular ngRepeat with the html5 audio tag. I have the html:

    <li ng-repeat="recordings in recordinglist">
        <audio controls ng-src="{{recordings}}"></audio>
   </li>

and the js:

    $scope.$apply($scope.recordinglist.push("blob:http%3A//localhost%3A9000/67ecfa65-3394-45a6-8f29-42f3421a2727"));

But angular's same origin checking is causing an error to be thrown on interpolation:

Error: [$interpolate:interr] Can't interpolate: {{recordings}}
Error: [$sce:insecurl] Blocked loading resource from url not allowed by $sceDelegate policy.  URL: blob:http%3A//localhost%3A9000/67ecfa65-3394-45a6-8f29-42f3421a2727

This just seems silly. It's not interpolating a local resource. I imagine there's a way to do this correctly - or should I file a bug report?

Stevo
  • 2,601
  • 3
  • 24
  • 32

5 Answers5

20

I have the same problem when trying to display a blob src for webrtc video before, and I fixed it by using $sce service:

angular.module('moduleName', ['ngSanitize'])
.controller('ctrName', ['$sce', function($sce) {
  $scope.recordings = $sce.trustAsResourceUrl(recordings);
}])

You may also check the doc here.

Don't Panic
  • 41,125
  • 10
  • 61
  • 80
fraserxu
  • 420
  • 3
  • 8
4

For me the following solved the problem:

$sce.trustAsResourceUrl

see SO question with more detailed explanation here

Community
  • 1
  • 1
elewinso
  • 2,453
  • 5
  • 22
  • 27
1

Faced a similar problem with my blob images... Try this:

Basically it allows any blob image in src

app.config( ['$compileProvider', function($compileProvider){   
  $compileProvider.imgSrcSanitizationWhitelist(/^\s*(blob):/);

  // another sample to allow diffrent kinds of url in <a>
  // $compileProvider.urlSanitizationWhitelist(/^\s*(https?|ftp|mailto):/);
}]);
Endless
  • 34,080
  • 13
  • 108
  • 131
0

Best way to solve this is to create a trusted filter.

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

And Use this filter in ng-src.

<li ng-repeat="recordings in recordinglist">
    <audio controls ng-src="{{recordings |trusted}}"></audio></li>

Hassan Siddique
  • 1,590
  • 14
  • 27
  • 1
    This defeats the entire purpose of SCE. You'd probably be better off just disabling it than creating a filter which any html could inject on the page maliciously. – RandallB Feb 24 '16 at 22:11
0

When getting the blob from a file reader, you might have to add $scope.$apply() to trigger the watch and bind accordingly.

InitRecording = function() {
    var reader = new FileReader();
    reader.onload = function() {
        audioSRC = $sce.trustAsResourceUrl(reader.result);
        $scope.$apply();
    };
    reader.readAsDataURL(recordedBlob);
}
Mahesh
  • 3,727
  • 1
  • 39
  • 49
  • You don't need FileReader... if you look carefully you see that the user has created a blob url using `URL.createObjectURL(blob)` – Endless Oct 24 '16 at 21:50
  • Exactly, and in case you are using a FileReader, and still facing the same error with '$sce', then $apply needs to be called, to trigger the watch variables changes – Mahesh Oct 24 '16 at 22:09