Surmonter "Affichage interdit par X-Frame-Options"

420

J'écris une petite page Web dont le but est d'encadrer quelques autres pages, simplement pour les consolider dans une seule fenêtre de navigateur pour en faciliter la visualisation. Certaines des pages que j'essaie d'encadrer interdisent d'être encadrées et lancent un "Refus d'afficher le document car l'affichage est interdit par X-Frame-Options". erreur dans Chrome. Je comprends qu'il s'agit d'une limitation de sécurité (pour une bonne raison), et je n'ai pas accès à la modifier.

Existe-t-il une autre méthode de cadrage ou de non-cadrage pour afficher les pages dans une seule fenêtre qui ne seront pas déclenchées par l'en-tête X-Frame-Options?

Garen Checkley
la source
117
Si ce sont vos pages, supprimez le limiteur de cadre. Sinon, respectez les souhaits de l'auteur de la page et ne les encadrez pas.
Marc B
Si vous obtenez cette erreur pour une application Facebook et que vous utilisez des appels AJAX, j'ai lu quelque part que Facebook aime vraiment utiliser # tags pour son contact ajax, alors essayez de changer les liens, j'ai travaillé pour moi.
eric.itzhak
28
@MarcB Chrome et Firefox cadrent éthiquement les sites Web non possédés dans l'interface utilisateur native de Chrome. Ces programmes permettent également à leurs propriétaires, FWIW, d'assouplir les politiques de même origine. Comme l'a dit garen-checkly, "J'écris une petite page Web dont le but est d'encadrer quelques autres pages, simplement pour les consolider dans une seule fenêtre de navigateur pour en faciliter la visualisation." Cela étendrait essentiellement le navigateur Web et serait complètement éthique. L'intention déclarée n'est pas différente de l'écriture d'un script bash pour ouvrir et organiser les fenêtres du navigateur.
Samuel Danielson
1
Vérifiez Surfly . Il peut faire exactement ce dont vous avez besoin.
muodov
1
@MarcB Ce n'est pas utile. OP pourrait ne pas se soucier des souhaits de l'auteur de la page.
flarn2006

Réponses:

211

J'ai eu un problème similaire, où j'essayais d'afficher le contenu de notre propre site dans un iframe (comme une boîte de dialogue de style lightbox avec Colorbox ), et où nous avions un en-tête "X-Frame-Options SAMEORIGIN" à l'échelle du serveur sur le serveur source l'empêchant de se charger sur notre serveur de test.

Cela ne semble être documenté nulle part, mais si vous pouvez modifier les pages que vous essayez d'iframe (par exemple, ce sont vos propres pages), envoyer simplement un autre en-tête X-Frame-Options avec n'importe quelle chaîne désactive les commandes SAMEORIGIN ou DENY.

par exemple. pour PHP, mise

<?php
    header('X-Frame-Options: GOFORIT'); 
?>

en haut de votre page, les navigateurs combineront les deux, ce qui donne un en-tête de

X-Frame-Options SAMEORIGIN, GOFORIT

... et vous permet de charger la page dans un iframe. Cela semble fonctionner lorsque la commande SAMEORIGIN initiale a été définie au niveau du serveur, et vous souhaitez la remplacer sur un cas page par page.

Bonne chance!

Sean
la source
3
J'avais un cadre autour d'un site Web. Sur mon site Web, je redirige vers Instagram pour OAUTH. Puisque Instagram envoie, X-Frame-Options: SAMEORIGINil n'y a aucun moyen de le faire à l'intérieur du cadre. Vous devez utiliser un popup.
Steve Tauber le
16
Avec PHP, il est probablement préférable d'utiliser la nouvelle header_removefonction, à condition qu'elle soit disponible (> = 5.3.0).
un chat
11
Ou vous pouvez éditer .htaccess si vous souhaitez supprimer X-Frame-Options d'un répertoire entier. Ajoutez simplement la ligne:Header always unset X-Frame-Options
Jay
4
@cawecoy: Eh bien oui, le fait est que ce n'est pas valide. Il s'appuie sur des navigateurs ignorant l'en-tête non valide et `` échec d'ouverture '', ce qui est un comportement non spécifié et assez douteux sur lequel s'appuyer. GOFORIT(ou un autre jeton invalide arbitraire aléatoire) enfreint délibérément une mesure de sécurité appliquée par un serveur; si vous avez le contrôle du serveur vous-même (ce que vous devriez faire pour tout service public réel), la bonne chose à faire est simplement de configurer le serveur pour ne pas définir l'en-tête en premier lieu.
bobince
31
Cela ne semble plus fonctionner dans Chrome. Des valeurs non valides entraînent la valeur par défaut DENY.
jamesfm
159

Si vous obtenez cette erreur pour une vidéo YouTube, plutôt que d'utiliser l'URL complète, utilisez l'URL intégrée des options de partage. Cela ressemblera àhttp://www.youtube.com/embed/eCfDxZxTBW4

Vous pouvez également remplacer watch?v=par devient embed/ainsihttp://www.youtube.com/watch?v=eCfDxZxTBW4http://www.youtube.com/embed/eCfDxZxTBW4

Wil
la source
14
Oh progrès ... Je souhaite qu'ils nous redirigent vers la page d'intégration au lieu de provoquer une erreur et de me faire réécrire mes scripts!
joeytwiddle
122

Si vous obtenez cette erreur en essayant d'incorporer une carte Google dans un iframe, vous devez l'ajouter &output=embedau lien source.

Q Studio
la source
120
Cela n'est vrai que pour l'intégration de google maps dans un iframe, et non une "solution" générale.
Benjamin Wohlwend
17
J'avais besoin d'intégrer une carte google dans une lightbox, donc cette "solution" était parfaite
yitwail
5
Si vous essayez de le faire avec une intention Web Twitter, oubliez-le. Je viens de perdre toute la journée à essayer différents plugins lightbox pour découvrir ceci "Bien que vous puissiez fournir des liens vers des intentions dans les IFRAME et les widgets, les pages résultantes ne peuvent pas être chargées dans un IFRAME." Source: site Web Twitter.
Gubatron
6
Cela ne fonctionne pas si vous essayez de charger l'iframe src après le chargement de la page restante même si vous ajoutez&output=embed
pathfinder
1
@pathfinder Cela a fonctionné pour moi lorsque j'ai eu du mal à charger l'iframe src après le chargement de la page
David Sykes
61

MISE À JOUR 2019: Vous pouvez contourner X-Frame-Optionsun <iframe>JavaScript côté client uniquement et mon composant Web X-Frame-Bypass . Voici une démo: Hacker News dans unX-Frame-Bypass . (Testé dans Chrome et Firefox.)

niutech
la source
3
C'est une solution intéressante. Fonctionne bien dans FF / Chrome / Opera mais ne fonctionne pas dans IE / Edge. Quelqu'un qui sait quelque chose qui le fera?
Collector
7
Cela ne marche plus. Il indique "Refusé d'afficher" news.ycombinator.com "dans un cadre car il a défini" X-Frame-Options "sur" DENY "." comme prévu
g.pickardou
2
@ g.pickardou Cela fonctionne pour moi dans Google Chrome 46, je peux voir Hacker News dans un iframe.
niutech
1
@niutech ce violon fonctionne après le rechargement de la page dans Chrome 64, mais la première fois que je charge la page, cela ne fonctionne pas. (Essayez incognito.)
Carl Walsh
1
Merci, c'est génial!
Andrew Gans
23

Ajout d'un

  target='_top'

à mon lien dans l'onglet facebook a résolu le problème pour moi ...

Kevin Vella
la source
1
J'ai eu le même problème avec l'iframe Paypal contenu dans un autre iframe. Ça fonctionne maintenant! Merci
Fabrizio Fortino
4
J'ai également ajouté target = '_ top', mais le problème avec cette solution est que le lien s'ouvre maintenant en dehors de l'iframe dans un nouvel onglet sans toile facebook.
sumitkanoje
23

Il existe un plugin pour Chrome, qui supprime cette entrée d'en-tête (pour un usage personnel uniquement):

https://chrome.google.com/webstore/detail/ignore-x-frame-headers/gleekbfjekiniecknbkamfmkohkpodhe/reviews


la source
@aup Il fait probablement quelques modifications dans la partie en-tête de la page Web.
L'extension ne fait aucun changement dans la page Web mais semble ignorer la validation de l'en-tête de réponse de la trame au niveau du navigateur
Vignesh Ammasi
13

J'ai eu le même problème lorsque j'ai essayé d'intégrer moodle 2 dans iframe, la solution est Site administration ► Security ► HTTP securityet vérifiezAllow frame embedding

Mohammad Ali Akbari
la source
bien fait pour la méthode moodle, car les autres méthodes échouent / sont écrasées.
ericosg
7

C'est la solution les gars !!

FB.Event.subscribe('edge.create', function(response) {
    window.top.location.href = 'url';
});

La seule chose qui a fonctionné pour les applications Facebook!

Konst
la source
6

Il semble que X-Frame-Options Allow-From https: // ... est déprécié et a été remplacé (et est ignoré) si vous utilisez Content-Security-Policy plutôt l'en tête .

Voici la référence complète: https://content-security-policy.com/

Dr. Aaron Dishno
la source
6

Solution pour charger un site Web externe dans un iFrame même difficile, l'option x-frame est définie pour être refusée sur le site Web externe.

Si vous souhaitez charger un autre site Web dans un iFrame et que vous obtenez l' Display forbidden by X-Frame-Options”erreur, vous pouvez réellement surmonter cela en créant un script proxy côté serveur.

L' srcattribut de l'iFrame pourrait avoir une URL ressemblant à ceci:/proxy.php?url=https://www.example.com/page&key=somekey

Ensuite, proxy.php ressemblerait à quelque chose comme:

if (isValidRequest()) {
   echo file_get_contents($_GET['url']);
}

function isValidRequest() {
    return $_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['key']) && 
    $_GET['key'] === 'somekey';
}

Cela passe le bloc, car il s'agit simplement d'une demande GET qui pourrait tout aussi bien être une visite de page de navigateur ordinaire.

Attention: vous souhaiterez peut-être améliorer la sécurité de ce script. Parce que les pirates pourraient commencer à charger des pages Web via votre script proxy.

Floris
la source
Je faisais cela il y a quelques semaines et toutes les URL relatives utilisées dans la page externe ne fonctionnent pas lors de l'utilisation d'écho. (En général, CSS et / ou JS, il est donc possible que vous n'obteniez pas toutes les fonctionnalités à moins de modifier les URL avant de faire écho.) Sauf si j'ai raté quelque chose ...,
ultrageek
Vous ne savez pas pourquoi cela se produit pour vous ... Cela devrait fonctionner comme une demande HTTP normale, tout comme un utilisateur final effectuerait lors de la visite de l'URL. Ainsi, le résultat de get_file_contents () devrait être une page HTML complètement fonctionnelle.
Floris
5

J'ai essayé presque toutes les suggestions. Cependant, la seule chose qui a vraiment résolu le problème était:

  1. Créez un .htaccessdans le même dossier où se trouve votre fichier PHP.

  2. Ajoutez cette ligne à htaccess:

    Header always unset X-Frame-Options

L'intégration du PHP par une iframe d'un autre domaine devrait fonctionner ensuite.

De plus, vous pouvez ajouter au début de votre fichier PHP:

header('X-Frame-Options: ALLOW');

Ce qui n'était cependant pas nécessaire dans mon cas.

Kai Noack
la source
En-tête toujours non défini X-Frame-Options dans htaccess a fait l'affaire pour moi
ujwal dhakal
4

J'ai eu le même problème avec mediawiki, c'est parce que le serveur a nié intégrer la page dans un iframe pour des raisons de sécurité.

Je l'ai résolu en écrivant

$wgEditPageFrameOptions = "SAMEORIGIN"; 

dans le fichier de configuration php de mediawiki.

J'espère que cela aide.

John White
la source
3

FWIW:

Nous avons eu une situation où nous devions tuer notre iFramelorsque ce code "disjoncteur" est apparu. J'ai donc utilisé le PHP function get_headers($url);pour vérifier l'URL distante avant de l'afficher dans un fichier iFrame. Pour de meilleures performances, j'ai mis les résultats en cache dans un fichier, donc je ne faisais pas de connexion HTTP à chaque fois.

Zane Claes
la source
3

J'utilisais Tomcat 8.0.30, aucune des suggestions n'a fonctionné pour moi. Comme nous cherchons à mettre à jour le X-Frame-Optionset à le définir ALLOW, voici comment j'ai configuré pour autoriser les iframes intégrés:

  • Accédez au répertoire Tomcat conf, modifiez le fichier web.xml
  • Ajoutez le filtre ci-dessous:
<filter>
            <filter-name>httpHeaderSecurity</filter-name>
            <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
                   <init-param>
                           <param-name>hstsEnabled</param-name>
                           <param-value>true</param-value>
                   </init-param>
                   <init-param>
                           <param-name>antiClickJackingEnabled</param-name>
                           <param-value>true</param-value>
                   </init-param>
                   <init-param>
                           <param-name>antiClickJackingOption</param-name>
                           <param-value>ALLOW-FROM</param-value>
                   </init-param>
            <async-supported>true</async-supported>
       </filter>

       <filter-mapping>
                   <filter-name>httpHeaderSecurity</filter-name>
                   <url-pattern>/*</url-pattern>
                   <dispatcher>REQUEST</dispatcher>
       </filter-mapping> 
  • Redémarrez le service Tomcat
  • Accédez aux ressources à l'aide d'un iFrame.
Giri
la source
2

La seule question qui a un tas de réponses. Bienvenue dans le guide que j'aurais aimé avoir quand je me battais pour que cela fonctionne à 10h30 le soir le jour limite ... FB fait des choses étranges avec des applications de toile, et bien, vous avez été prévenu. Si vous êtes toujours là et que vous avez une application Rails qui apparaîtra derrière un canevas Facebook, vous aurez besoin de:

Gemfile:

gem "rack-facebook-signed-request", :git => 'git://github.com/cmer/rack-facebook-signed-request.git'

config / facebook.yml

facebook:
  key: "123123123123"
  secret: "123123123123123123secret12312"

config / application.rb

config.middleware.use Rack::Facebook::SignedRequest, app_id: "123123123123", secret: "123123123123123123secret12312", inject_facebook: false

config / initializers / omniauth.rb

OmniAuth.config.logger = Rails.logger
SERVICES = YAML.load(File.open("#{::Rails.root}/config/oauth.yml").read)
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :facebook, SERVICES['facebook']['key'], SERVICES['facebook']['secret'], iframe:   true
end

application_controller.rb

before_filter :add_xframe
def add_xframe
  headers['X-Frame-Options'] = 'GOFORIT'
end

Vous avez besoin d'un contrôleur pour appeler à partir des paramètres de toile de Facebook, j'ai utilisé /canvas/et fait que l'itinéraire devienne le principal SiteControllerpour cette application:


class SiteController < ApplicationController
  def index
    @user = User.new
  end
  def canvas
    redirect_to '/auth/failure' if request.params['error'] == 'access_denied'
    url = params['code'] ? "/auth/facebook?signed_request=#{params['signed_request']}&state=canvas" : "/login"
    redirect_to url
  end
  def login
  end
end

login.html.erb


<% content_for :javascript do %>
  var oauth_url = 'https://www.facebook.com/dialog/oauth/';
  oauth_url += '?client_id=471466299609256';
  oauth_url += '&redirect_uri=' + encodeURIComponent('https://apps.facebook.com/wellbeingtracker/');
  oauth_url += '&scope=email,status_update,publish_stream';
console.log(oauth_url);
  top.location.href = oauth_url;
<% end %>

Sources

  • Je pense que la configuration vient de l'exemple d'Omniauth.
  • Le fichier gem (qui est la clé !!!) est venu de: SlideShare choses que j'ai apprises ...
  • Cette question de pile avait tout l'angle Xframe, donc vous obtiendrez un espace vide, si vous ne placez pas cet en-tête dans le contrôleur d'application.
  • Et mon homme @rafmagana a écrit ce guide heroku , que vous pouvez maintenant adopter pour les rails avec cette réponse et les épaules des géants dans lesquels vous marchez.
pjammer
la source
2

target = '_ parent'

En utilisant l'idée de Kevin Vella, j'ai essayé d'ajouter cet attribut aux éléments de formulaire créés par le générateur de boutons de PayPal. A fonctionné pour moi afin que Paypal ne s'ouvre pas dans une nouvelle fenêtre / onglet de navigateur.

jiminikiz
la source
Malheureusement, cela ne semble pas fonctionner aussi pour les safaris.
Wtower
1

Je ne sais pas à quel point c'est pertinent, mais j'ai construit une solution à cela. Sur mon site, je voulais afficher un lien dans une fenêtre modale contenant un iframe qui charge l'URL.

Ce que j'ai fait, c'est que j'ai lié l'événement de clic du lien à cette fonction javascript. Tout cela ne fait que faire une demande à un fichier PHP qui vérifie les en-têtes d'URL pour X-FRAME-Options avant de décider de charger l'URL dans la fenêtre modale ou de rediriger.

Voici la fonction:

  function opentheater(link, title){
        $.get( "url_origin_helper.php?url="+encodeURIComponent(link), function( data ) {
  if(data == "ya"){
      $(".modal-title").html("<h3 style='color:480060;'>"+title+"&nbsp;&nbsp;&nbsp;<small>"+link+"</small></h3>");
        $("#linkcontent").attr("src", link);
        $("#myModal").modal("show");
  }
  else{
      window.location.href = link;
      //alert(data);
  }
});


        }

Voici le code du fichier PHP qui le vérifie:

<?php
$url = rawurldecode($_REQUEST['url']);
$header = get_headers($url, 1);
if(array_key_exists("X-Frame-Options", $header)){
    echo "nein";
}
else{
    echo "ya";
}


?>

J'espère que cela t'aides.

swatkat7
la source
1

J'ai rencontré ce problème lors de l'exécution d'un site Web wordpress. J'ai essayé toutes sortes de choses pour le réparer et je ne savais pas comment, finalement le problème était parce que j'utilisais le transfert DNS avec masquage et que les liens vers des sites externes n'étaient pas traités correctement. c'est-à-dire que mon site a été hébergé à http: //123.456.789/index.html mais a été masqué pour fonctionner à http://somewebSite.com/index.html . Quand je suis entré, http: //123.456.789/index.html l'a dans le navigateur en cliquant sur ces mêmes liens, il n'y a eu aucun problème d'origine X-frame dans la console JS, mais en exécutant http://somewebSite.com/index.htmlfait. Pour masquer correctement, vous devez ajouter les serveurs de noms DNS de votre hôte à votre service de domaine, c'est-à-dire que godaddy.com devrait avoir des serveurs de noms, par exemple, ns1.digitalocean.com, ns2.digitalocean.com, ns3.digitalocean.com, si vous étiez en utilisant digitalocean.com comme service d'hébergement.

kinghenry14
la source
1
J'ai fini par faire: remove_action( 'admin_init', 'send_frame_options_header',10);contourner ce problème ...
majick
1

Il est surprenant que personne ici n'ait jamais mentionné Apacheles paramètres ( *.conffichiers) du serveur ou le .htaccessfichier lui-même comme étant la cause de cette erreur. Recherchez dans vos fichiers de configuration .htaccessou Apache, en vous assurant que vous n'avez pas l'ensemble suivant DENY:

Header always set X-Frame-Options DENY

Le changer en SAMEORIGIN, fait fonctionner les choses comme prévu:

Header always set X-Frame-Options SAMEORIGIN

Ilia Rostovtsev
la source
cela a déjà été mentionné - voir le commentaire de @Jay sur la réponse stackoverflow.com/a/6767901/1875965
Sandra
Je configure l'en-tête du fichier .conf toujours défini X-Frame-Options SAMEORIGIN!
GeekHades
Mais comment est-ce pertinent pour la question ici, où l'en-tête provient de serveurs étrangers , directement au client , IOW votre propre serveur n'est même pas impliqué? Suis-je en train de manquer quelque chose?
Sz.
1

La seule vraie réponse, si vous ne contrôlez pas les en-têtes sur votre source que vous voulez dans votre iframe, est de le proxy. Demandez à un serveur d'agir en tant que client, recevez la source, supprimez les en-têtes problématiques, ajoutez CORS si nécessaire, puis envoyez une requête ping à votre propre serveur.

Il y a une autre réponse expliquant comment écrire un tel proxy. Ce n'est pas difficile, mais j'étais sûr que quelqu'un devait le faire auparavant. Il était juste difficile de le trouver, pour une raison quelconque.

J'ai finalement trouvé quelques sources:

https://github.com/Rob--W/cors-anywhere/#documentation

^ préféré. Si vous avez besoin d'une utilisation rare, je pense que vous pouvez simplement utiliser son application Heroku. Sinon, c'est du code pour l'exécuter vous-même sur votre propre serveur. Notez bien quelles sont les limites.

anyorigin.org

^ deuxième choix, mais assez ancien. choix supposément plus récent en python: https://github.com/Eiledon/alloworigin

puis il y a le troisième choix:

http://anyorigin.com/

Ce qui semble permettre un peu d'utilisation gratuite, mais vous placera sur une liste de honte publique si vous ne payez pas et utilisez un montant non spécifié, dont vous ne pouvez être retiré que si vous payez les frais ...

Kyle Baker
la source
0

Non mentionné mais peut aider dans certains cas:

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (xhr.readyState !== 4) return;
    if (xhr.status === 200) {
        var doc = iframe.contentWindow.document;
        doc.open();
        doc.write(xhr.responseText);
        doc.close();
    }
}
xhr.open('GET', url, true);
xhr.send(null);
mattdlockyer
la source
0

Utilisez cette ligne donnée ci-dessous au lieu de la header()fonction.

echo "<script>window.top.location = 'https://apps.facebook.com/yourappnamespace/';</script>";
Hemanta Nandi
la source
0

j'ai eu ce problème et l' ai résolu en modifiant httd.conf

<IfModule headers_module>
    <IfVersion >= 2.4.7 >
        Header always setifempty X-Frame-Options GOFORIT
    </IfVersion>
    <IfVersion < 2.4.7 >
        Header always merge X-Frame-Options GOFORIT
    </IfVersion>
</IfModule>

j'ai changé SAMEORIGIN en GOFORIT et redémarré le serveur

Arthur Tsidkilov
la source
-1

Essayez cette chose, je ne pense pas que quelqu'un ait suggéré cela dans le sujet, cela résoudra comme 70% de votre problème, pour certaines autres pages, vous devez supprimer, j'ai la solution complète mais pas pour le public,

AJOUTER ci-dessous à votre iframe

sandbox = "allow-same-origin allow-scripts allow-popups allow-forms"

Zulqurnain abbas
la source
1
le sandboxing réduit les privilèges, il ne les ajoute pas. voir html5rocks.com/en/tutorials/security/sandboxed-iframes
Kyle Baker