web-dev-qa-db-fra.com

Utilisation d'iFrames dans AngularJS

En utilisant Angular 1.2+, J'essaie de trouver un moyen "angulaire" de charger dans un iFrame mais je ne trouve aucun tutoriel/aucune discussion réelle à ce sujet.

Fondamentalement, j'ai une page de recherche qui affiche une liste de liens. Cliquer sur un lien devrait appeler une fonction dans mon contrôleur qui charge les données (éventuellement via le service $ http?) Vers un iFrame tout en gardant les résultats de la recherche en vue.

Voici du code rudimentaire (je n'ai jamais vraiment utilisé iFrames auparavant donc je m'excuse si c'est tout simplement faux)

Voir

<div ng-controller="searchPage">
  <div ng-repeat='post in searchResults'>
    <a ng-click="itemDetail(post._infoLink)">Here's a link!</a>
  </div>
  <div class="detailView" ng-show="itemShown">
    <iframe ng-src="detailFrame"></iframe>
  </div>
</div>

Contrôleur

$scope.itemDetail = function(link){
  $scope.itemShown = true;
  $scope.busy = true;
  $http.get(link).success(function(data){
    $scope.busy = false;
    $scope.detailFrame = data;
  });
}

Ce code donne actuellement l'erreur:

 XMLHttpRequest cannot load <url>. Origin http://localhost:5000 is not allowed by Access-Control-Allow-Origin. 

Quelque chose de simple dans ce sens serait idéal. Dans l'exemple (tenté) ci-dessus, les résultats de la recherche resteraient à l'écran et seraient poussés dans une barre latérale, tandis que l'iFrame se charge dans un site externe (sur un domaine différent) dans la majeure partie de la page.

Comment cela peut-il être réalisé avec Angular?

Avertissement supplémentaire: les liens à charger dans l'iFrame sont des liens d'affiliation, de sorte qu'ils auront souvent un domaine `` intermédiaire '' entre eux, par exemple le lien cliqué sera mydomain.com/cloakinglink qui redirige vers www.zanox.com/whatever qui mène ensuite au site final, www.asos.com/whatever.

11
JVG

En raison de même politique d'origine , vous ne pouvez pas obtenir de données interdomaines en utilisant XMLHttpRequest.

Je ne suis pas tout à fait sûr de ce que vous voulez vraiment faire.

Vous pouvez essayer de lier l'attribut src iframe et l'url du lien cliqué ensemble pour obtenir la fonction si vous voulez simplement que iframe affiche la page Web sur laquelle l'utilisateur a cliqué.

J'ai écrit un exemple simple:

[~ # ~] html [~ # ~]

<div ng-app ng-controller="searchPage">
  <div ng-repeat="page in searchResults">
      <a ng-click="itemDetail(page._infoLink)">{{page.label}}</a>
  </div>
  <iframe width="500" height="400" ng-src="{{detailFrame}}"></iframe>
</div>

[~ # ~] js [~ # ~]

function searchPage($scope){
  $scope.searchResults = [{label:"BBC",_infoLink:"http://www.bbc.co.uk/"},{label:"CNN",_infoLink:"http://edition.cnn.com/"}];

  $scope.itemDetail = function(link){
      $scope.detailFrame = link;
  };
}

Voici la démo jsFiddle

BTW ... Vous pouvez essayer le serveur proxy si vous voulez vraiment utiliser XMLHttpRequest pour récupérer les données d'un site Web tiers et les vider quelque part (vous ne pouvez pas vider les données vers l'attribut iframe src! Il accepte uniquement l'URL de la page Web ).

8
Chickenrice

Comme pour AngularJS 1.2, vous devez utiliser le $sce un service:

<iframe width="500" height="400" ng-src="{{detailFrame}}"></iframe>

$scope.detailFrame= $sce.trustAsResourceUrl("http://www.google.com");

Bonne chance...

16
TidharPeer

Vraiment du mal à utiliser simplement dom pour st iframe.src. Grr ... Angular incline la lumière vers elle.

 .state('nav.iframer', {
            url: '/iframer',
            templateUrl: 'app/dashboard/iframer.html',
            controller: function($rootScope, $sce){


                    var f = window.frames.iframer;//
                    this.frameUrl= $sce.trustAsResourceUrl("http://www.google.com");


            },

            controllerAs: 'framed'
        })

modèle:

<iframe name="iframer" width="900" height="900" ng-src="{{framed.frameUrl}}"></iframe>
4
httpete

Je pense que des éclaircissements supplémentaires sont nécessaires ainsi qu'un autre exemple.

$ sce est un service que vous DEVEZ injecter. La raison pour laquelle il n'est pas inclus automatiquement est la surcharge de performances, vous VOULEZ certainement pouvoir charger uniquement les services dont vous avez besoin.

$ sce.trustasResourceURL est donc important

Exemple:

angular.module('tips')

.controller('TipsCtrl',

function ($http, $scope, UserService, $location, $routeParams, Categories, Tip, error, $sce) {  
    // various code  
    $scope.detailFrame = $sce.trustAsResourceUrl("http://localhost:17308/Home/Index/2"); //hard coded
})

Ensuite, l'IFrame:

<iframe ng-src="{{detailFrame}}" align="middle" width="1000" height="800" frameborder="0">
    <p>Your browser does not support iframes.</p>
</iframe>
3
Tom Stickel