在使用AngularJS的Chrome应用程序中,我可以直接对内部图像使用ngSrc指令吗?

在使用AngularJS的Chrome应用程序中,我可以直接对内部图像使用ngSrc指令吗?,angularjs,google-chrome-app,Angularjs,Google Chrome App,我正在用AngularJS编写一个Chrome应用程序。我知道,在访问外部图像时,必须执行跨源XMLHttpRequest并将其作为blob提供 我有一堆内部图像(本地应用程序资源),它们遵循我希望在ngRepeat中显示的模式 我可以通过以下方式静态加载图像: <img src="images/image1.png"/> 我已经能够使用ngsrc和XHR成功地加载外部资源。对于动态加载的内部资源,是否必须遵循相同的模式 更新-另一个简单的例子 从最简单的Chrome应用程序()开

我正在用AngularJS编写一个Chrome应用程序。我知道,在访问外部图像时,必须执行跨源XMLHttpRequest并将其作为blob提供

我有一堆内部图像(本地应用程序资源),它们遵循我希望在ngRepeat中显示的模式

我可以通过以下方式静态加载图像:

<img src="images/image1.png"/>
我已经能够使用ngsrc和XHR成功地加载外部资源。对于动态加载的内部资源,是否必须遵循相同的模式

更新-另一个简单的例子 从最简单的Chrome应用程序()开始,以下内容将在Chrome应用程序外部(在浏览器中)工作,但不在Chrome应用程序内工作:

index.html

<!DOCTYPE html>
<html ng-app ng-csp>
<head>
    <title>Hello World</title>
    <script src="js/angular.min.js"></script>
    <script src="js/test.js"></script>
</head>
<body ng-controller="Ctrl">
    <img ng-src="{{imageUrl}}"/>
</body>
</html>

尝试通过如下函数运行每个映像src

<div ng-repeat="item in myList">
    <img ng-src="{{trustAsResourcUrl(item.imageUrl)}}"/>
</div>
别忘了包括$sce服务。您还可以尝试完全禁用SCE以 消除它

angular.module('myAppWithSceDisabledmyApp', []).config(function($sceProvider) {
    // Completely disable SCE.  For demonstration purposes only!
    // Do not use in new projects.
    $sceProvider.enabled(false);

});

我刚刚在另一个堆栈溢出问题中找到了答案:

Angular有一个白名单正则表达式,在Angular更改src之前,图像src url必须匹配该表达式。默认情况下,chrome扩展名://url与之不匹配,因此您必须更改它。有关更多信息,请参见此处:

$compileProvider

我添加了以下代码以允许将chrome扩展//URL添加到白名单(使用另一个stackoverflow问题答案中的代码):


我的方法不是使用ng src

我为Chrome安全策略编写了onw csp src

angular.module('myAppInChromeApp',[]).directive('cspSrc', function () {
    return {
        restrict: 'A',
        replace: false,
        priority: 99, //after all build-in directive are compiled
        link: function(scope, element, attrs) {
            attrs.$observe('ngSrc', function(value) {
                if (!value)
                    return;

                if(element[0].nodeName.toLowerCase() === 'img' && value.indexOf('blob') != 0){
                    //if it is img tag then use XHR to load image.
                    var localSrc = null;
                    var xhr = new XMLHttpRequest();
                    xhr.open('GET', value, true);
                    xhr.responseType = 'blob';
                    xhr.onload = function (e) {
                        localSrc = URL.createObjectURL(this.response);
                    };
                    xhr.send();
                    scope.$on("$destroy", function() {
                        localSrc && URL.revokeObjectURL(localSrc);
                    });
                    attrs.$set('src', localSrc);

                }else{
                    attrs.$set('src', value);
                }
            });
        }
    };
})
并将ng src更改为csp src

<img csp-src="http://yourimage.jpg"/>


当然,您可以添加更多条件,使csp src同时适用于网站和chromeapp,使其基于Eric Chen的响应工作,创建如下指令:

<div ng-repeat="item in myList">
    <img ng-src="{{item.imageUrl}}"/>
</div>
Refused to load the image 'unsafe:chrome-extension://hcdb...flhk/images/image1.png' because it violates the following Content Security Policy directive: "img-src 'self' data: chrome-extension-resource:".
angular.module('myAppInChromeApp',[]).directive('cspSrc',function(){
返回{
限制:“A”,
替换:false,
优先级:99,//编译完所有内置指令后
链接:函数(范围、元素、属性){
属性$observe('cspSrc',函数(值){
如果(!值)
返回;
if(元素[0].nodeName.toLowerCase()=='img'&&value.indexOf('blob')!==0){
//如果是img标记,则使用XHR加载图像。
var localSrc=null;
var xhr=new XMLHttpRequest();
xhr.open('GET',value,true);
xhr.responseType='blob';
xhr.onload=函数(e){
localSrc=URL.createObjectURL(this.response);
元素[0]。src=localSrc;
};
xhr.send();
作用域:$on(“$destroy”,函数(){
if(localSrc){
revokeObjectURL(localSrc);
}
});
}否则{
属性$set('src',值);
}
});
}
};
})

)

与前面给出的答案类似,下面是一个覆盖AngluarJs正则表达式的函数,用于将img src URL白名单

基本上,angular js不会信任包含在ng src标记中的url,而是会尝试验证/清理它们。此过程的结果是,该标记中提供的url前面将有一个“不安全:”字符串。这进而决定chrome运行时不显示图像,因为它无法找到位于“unsafe:/path/to/image/img.jpg”的图像

所以,我们要做的是覆盖列有img src URL白名单的正则表达式。a href URL也有类似的正则表达式。为此,您必须阅读angular js文档

appModule是angular js应用程序中的主要应用程序模块

appModule.config([
  '$compileProvider',
  function ($compileProvider) {
      //  Default imgSrcSanitizationWhitelist: /^\s*((https?|ftp|file|blob):|data:image\/)/
      //  chrome-extension: will be added to the end of the expression
      $compileProvider.imgSrcSanitizationWhitelist(/^\s*((https?|ftp|file|blob|chrome-extension):|data:image\/)/);
  }
]);

我刚试过你的建议。在最初忘记包含$sce服务(尽管有提醒)之后,我又回到了以前的错误(尽管我仔细检查了它是通过$sce.trustAsResourceUrl实现的)。尝试完全禁用sce,看看这是问题还是其他问题。我更新了我的答案。我也尝试了你的第二个建议,但仍然有同样的错误。我在这里找到了答案:它起作用了。但是改变
$compileProvider
不是个坏主意吗?
angular.module('myAppInChromeApp',[]).directive('cspSrc', function () {
    return {
        restrict: 'A',
        replace: false,
        priority: 99, //after all build-in directive are compiled
        link: function(scope, element, attrs) {
            attrs.$observe('ngSrc', function(value) {
                if (!value)
                    return;

                if(element[0].nodeName.toLowerCase() === 'img' && value.indexOf('blob') != 0){
                    //if it is img tag then use XHR to load image.
                    var localSrc = null;
                    var xhr = new XMLHttpRequest();
                    xhr.open('GET', value, true);
                    xhr.responseType = 'blob';
                    xhr.onload = function (e) {
                        localSrc = URL.createObjectURL(this.response);
                    };
                    xhr.send();
                    scope.$on("$destroy", function() {
                        localSrc && URL.revokeObjectURL(localSrc);
                    });
                    attrs.$set('src', localSrc);

                }else{
                    attrs.$set('src', value);
                }
            });
        }
    };
})
<img csp-src="http://yourimage.jpg"/>
appModule.config([
  '$compileProvider',
  function ($compileProvider) {
      //  Default imgSrcSanitizationWhitelist: /^\s*((https?|ftp|file|blob):|data:image\/)/
      //  chrome-extension: will be added to the end of the expression
      $compileProvider.imgSrcSanitizationWhitelist(/^\s*((https?|ftp|file|blob|chrome-extension):|data:image\/)/);
  }
]);