如果 iframe 无法在 src 加载资源,如何显示替代图像?使用 AngularJs?

Posted

技术标签:

【中文标题】如果 iframe 无法在 src 加载资源,如何显示替代图像?使用 AngularJs?【英文标题】:How to show alternative image if Iframe can't load the resource at src ? Using AngularJs? 【发布时间】:2015-02-17 06:59:07 【问题描述】:

我在我的一个jsp页面中使用iframe,我需要分配一个外部地址作为这个iframe的src。它按预期工作。但是,有时当外部源不可用时,我想显示静态图像。我尝试了很多方法,但都没有成功。

比我尝试使用 AngularJS (我最新的迷恋)的方式来实现这一点,但看起来我错过了一些东西。我的文件中的一部分附在下面:-

<iframe ng-src="iframesrcurl" frameborder="0"   scrolling="auto" onload="load($event)" onerror="loadingError">
                                <h3>No such page</h3>
</iframe>

JS文件有

myAppName.controller("myAppController", function ($scope, $sce) 
    $scope.iframesrcurl=$sce.trustAsResourceUrl('http://www.w3schools.com');
    console.log('iframesrcurl is '+$scope.iframesrcurl);
);

function load(e) 
    alert("Inside load function");
    alert(e);


function loadingError() 
    alert('Inside error function');

问题是 onload 并且永远不会调用 onerror 函数。

请指导我。我正在寻找纯 htmljavascript 或 Angular 的方法,但 jquery 特定的技巧也将不胜感激。

编辑

This question 类似,但它使用的是 knockout.js,我不允许在我的项目中使用它。请建议 Angular 的做法。

【问题讨论】:

您所做的不是“角度”方式。这是角度方式的开始:***.com/questions/15882326/… @JaimeTorres 感谢您的链接。但是,当外部资源不可用时,我无法收到任何通知。 onError 部分不起作用。如果您有任何工作演示,请分享。 出于安全考虑,没有适用于跨站点 URL 的“onError”。如果页面在您的域中,您可以简单地检查框架的内容并确定它是否有意义。如果你试图加载外部资源,你可能是 SOL。一个 plnkr 用于对你所做的事情进行角化:plnkr.co/edit/jTmWOLMN7LdiCZPIvuof 我从未尝试过,但这种 YQL 用法可能会起作用:***.com/a/16756395/1497479 【参考方案1】:

我最初以与您的回调相匹配的非常复杂的方法回答了您的问题。然后我重新阅读了您的问题,并意识到这不是目标。目标是创建显示图像或框架的东西。假设该框架需要离开您的域(基于您对 $sce 的使用,我相信是这种情况),此解决方案将起作用。

完整的 Plnkr:http://embed.plnkr.co/jTmWOLMN7LdiCZPIvuof/preview

HTML:

  <body ng-app='myApp' ng-controller="myAppController">
    <h1>Hello ***!</h1>

    <iframe-nanny desired-uri="desiredFrameSource" error-image-uri="errorImageSrc"></iframe-nanny>
  </body>

控制器:

myAppName.controller("myAppController", function($scope, $sce) 
  $scope.desiredFrameSource = 'http://www.w3schools.com/test';
  $scope.errorImageSrc = 'https://cdn2.iconfinder.com/data/icons/contact-flat-buttons/512/thumb_down-512.png';
);

为方便起见,我们在控制器中定义了 URL。这些显然是可变的。要测试失败的 URI,我们可以使用

  $scope.desiredFrameSource = 'http://www.w3schools.com/test';

测试成功的 URI:

  $scope.desiredFrameSource = 'http://www.w3schools.com/';

我希望足够简单。魔法现在发生在指令中。它根据 YQL 查询的结果发出 iframe 或图像。如果您需要额外的警报,您可以向指令发送回调/属性并用它做一些可爱的事情。

指令:

myAppName.directive('iframeNanny', function($q, $http, $compile, $sce) 
  return 
    restrict: 'E',
    scope: 
      desiredUri: '=',
      errorImageUri: '='
    ,
    link: function(scope, element, attrs) 
      var loadedUri = '';

      function isURLReal(fullyQualifiedURL) 
        var URL = encodeURIComponent(fullyQualifiedURL);
        var dfd = $q.defer();
        var yqlUri = 'http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22' + URL + '%22&callback=JSON_CALLBACK';

        $http.jsonp(yqlUri)
          .success(function(data, status) 
            console.log(data.results.length);
            if (data.results.length) 
              console.log('success!')
              dfd.resolve(true);
             else 
              dfd.reject(false);
            
          ).error(function(data, status) 
            dfd.reject('failed');
          );

        return dfd.promise;
      

      scope.$watch('desiredUri', function(uri) 
        if (loadedUri !== uri) 

          isURLReal(uri).then(function()  
            console.log('directive: uri valid');
            loadedUri = uri;

            scope.trustedUri = $sce.trustAsResourceUrl(scope.desiredUri);

            var iFrameHtml = '<iframe src="trustedUri" frameborder="0"   scrolling="auto"></iframe>';

            var markup = $compile(iFrameHtml)(scope);
            element.empty();
            element.append(markup);
          ).catch(function() 
            console.log('directive: uri invalid');
            var badRequestImgHtml = '<img src="errorImageUri">';

            var markup = $compile(badRequestImgHtml)(scope);

            console.log(scope.errorImageUri);
            element.empty();
            element.append(markup);
          );
        
      );
    
  ;
);

这是一个需要解决的有趣问题。好问题!

【讨论】:

谢谢@Jaime,看起来他们的 plunker 代码有问题,他们没有按预期工作。 plunker 有什么问题?当我更改 url 时,它似乎可以工作,在图像和 w3schools 页面之间切换取决于 url 中是否存在“test”。 我现在开始工作了.. 感谢您的帮助。我真的很感激。他们有什么其他方法可以避免使用 YQL 吗? 是的。如果您的所有请求都在您的域上,或者您可以控制服务器端并且您可以将服务器用作请求的代理,那么您不受 CORS 的限制。除非您正在联系的属性在其标头中使用适当的“Access-Control-Allow-Origin”进行响应,否则您将需要某种形式的代理,因为安全限制会发出请求,更不用说询问它的结果了。

以上是关于如果 iframe 无法在 src 加载资源,如何显示替代图像?使用 AngularJs?的主要内容,如果未能解决你的问题,请参考以下文章

每次进入iframe都重新加载

无法阻止加载iframe

动态设置 iframe 的 src 以延迟加载

如何在一个页面上加载具有相同 src 的多个 iframe

检测 iframe 加载错误

iFrame 无法在手机或平板电脑上加载