在<img>标签中使用CDN

3

我刚刚添加了一个CDN服务,以加快我的网站加载速度。 关于使用<img>标签获取的照片,我有一个问题。

我有很多类似这样的情况:

// userProfile.thumbnailPhotoSrc = some/relative/path.png    
ng-src="{{userProfile.thumbnailPhotoSrc}}"

我使用AngularJS。

在启动时,我有一个脚本将CDN端点保存到window.cdn变量中。如果脚本决定没有可用的端点:

window.cdn = '';

所以我希望能够做到这样:

ng-src="window.cdn + {{userProfile.thumbnailPhotoSrc}"

但这是不可能的,因为 window.cdn 没有被评估。但是以下方法也不起作用:
ng-src="{{window.cdn + userProfile.thumbnailPhotoSrc}"

因为我只能在{{}}下访问$scope属性。 我不能将CDN端点保存到$scope中,因为每个控制器都存在一个$scope(我有很多个,这是不可维护的)。
我想到的最后一件事,希望ng-src允许 - 是添加一个转换函数,该函数在任何ng-src属性上运行,但我找不到如何做到这一点。
你有什么建议?请记住,我希望网站从CDN获取照片,并在CDN故障的情况下回退到原始服务器(获取相对路径)。我怎样才能获得这种行为?
谢谢

嗨Johni,你是如何从CDN获取图像的?最终你是否想要调用API端点来检索图像数据?另外,小提示 - 你不需要在引号内使用"{{}}"。有时这会导致问题。 - socialpiranha
我使用与 userProfile.thumbnailPhotoSrc 相同的相对路径,只是换了一个不同的域名。例如:'https://blabla.cdn.com/' + {{userProfile.thumbnailPhotoSrc}} - 将被解析为 CDN 的正确地址。 - johni
我认为这可能会有帮助:https://dev59.com/TGct5IYBdhLWcg3wpO7H - Hoyen
在你的示例代码中,你写了 window.CDNwindow.cdn。这是偶然的吗?还是可能与你的问题有关? - Daniel Diekmeier
不小心地 :), 已编辑。 - johni
2个回答

4
你可以在Angular中创建一个自定义过滤器
然后,在你的模板中使用它:
ng-src="{{userProfile.thumbnailPhotoSrc | cdn}"

你可以将 $window 服务添加为筛选器服务的依赖项,这样你就不必从全局对象中提取它,也可以测试筛选器。

这很好,我之前不知道,但是如果我有1000个<img>标签怎么办?我需要遍历所有这些标签。我正在寻找一种避免这种情况的方法。 - johni
@johni - 如果您不想将1000个img标签通过过滤器推送,那么您处理它们的方式肯定是一样的吧? - Quentin

1
如果您想更新所有<img>标签的src,您可以创建一个指令:
angular.module('imageCdnSrc', [])
.directive('img',['$interpolate', function($interpolate) {
    return {
    restrict: 'E',
    scope: false,
    compile: function(element, attrs) {
      var ngSrc = attrs.ngSrc;
      delete attrs.ngSrc; // prevent ngSrc directive to trigger

      return function($scope,element,attrs) {
        var ngSrcVal = $interpolate(ngSrc)($scope); //returns the string value of ngSrc

        /* Add Logic Below to decide what to do */
        if(window.cdn && ngSrcVal && ngSrcVal.length>0){
          attrs.ngSrc = window.cdn + ngSrcVal;
          /* if image fails to load with cdn, load the default */
          element.one('error', function() {
            angular.element(this).attr("src", ngSrcVal);
          });
        }
        else{
          attrs.ngSrc = ngSrcVal;
        }
      };      
    }
  };
}]);

这是什么让它在ngSrc指令的$observe回调之前执行? - johni
@johni 好的,我更新了,现在在编译之前它会将 window.cdn 添加到 th ngSrc。 - Hoyen
ng-src="{{userProfile.thumbnailPhotoSrc}}" 的情况下,指令的编译函数会在 {{}} 被评估之前被调用。 - johni
@johni 是的,就是这样工作的。在两者之后,img 'src' 不会呈现。这是它在 plunker 上运行的示例。http://plnkr.co/edit/PGNWoF1w1OdmEFUSglKw?p=info - Hoyen
@johni 我刚刚更新了代码,以便在评估之前和之后进行演示。 - Hoyen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接