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

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

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

<iframe ng-src="{{iframesrcurl}}" frameborder="0" width="100%" height="1100px" 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 函数。

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

编辑

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

【问题讨论】:

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

标签: javascript jquery html angularjs iframe


【解决方案1】:

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

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

HTML:

  <body ng-app='myApp' ng-controller="myAppController">
    <h1>Hello StackOverflow!</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" width="100%" height="1100px" 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”进行响应,否则您将需要某种形式的代理,因为安全限制会发出请求,更不用说询问它的结果了。
猜你喜欢
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 2011-10-01
  • 2022-01-09
  • 1970-01-01
  • 2016-07-13
  • 1970-01-01
  • 2015-01-20
相关资源
最近更新 更多