109 votes

Est-il possible d'ajouter des en-têtes de demande à une demande de src iframe ?

J'ai cru comprendre que vous pouviez définir très facilement les en-têtes de requête HTTP lorsque vous effectuez des appels AJAX en JavaScript.

Cependant, est-il également possible de définir des en-têtes de requête HTTP personnalisés lors de l'insertion d'une iframe dans une page via script ?

<iframe src="someURL"> <!-- is there any place to set headers in this? -->

103voto

FellowMD Points 109

Vous pouvez effectuer la demande en javascript, en définissant les en-têtes que vous souhaitez. Ensuite, vous pouvez URL.createObjectURL() pour obtenir quelque chose de convenable pour le src de l'iframe.

var xhr = new XMLHttpRequest();

xhr.open('GET', 'page.html');
xhr.onreadystatechange = handler;
xhr.responseType = 'blob';
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
xhr.send();

function handler() {
  if (this.readyState === this.DONE) {
    if (this.status === 200) {
      // this.response is a Blob, because we set responseType above
      var data_url = URL.createObjectURL(this.response);
      document.querySelector('#output-frame-id').src = data_url;
    } else {
      console.error('no pdf :(');
    }
  }
}

Le type MIME de la réponse est préservé. Ainsi, si vous obtenez une réponse html, le html s'affichera dans l'iframe. Si vous avez demandé un pdf, la visionneuse de pdf du navigateur s'affichera dans la iframe.

Si cette application fait partie d'une application côté client à longue durée de vie, vous voudrez peut-être utiliser URL.revokeObjectURL() pour éviter les fuites de mémoire.

Les URL des objets sont également très intéressants. Elles sont de la forme blob:https://your.domain/1e8def13-3817-4eab-ad8a-160923995170 . Vous pouvez en fait les ouvrir dans un nouvel onglet et voir la réponse, et ils sont supprimés lorsque le contexte qui les a créés est fermé.

Voici un exemple complet : https://github.com/courajs/pdf-poc

41voto

Niet the Dark Absol Points 154811

Non, tu ne peux pas. Cependant, vous pouvez définir le iframe à une sorte de script de préchargement, qui utilise AJAX pour récupérer la page actuelle avec tous les en-têtes que vous voulez.

8voto

poiuytrez Points 2854

Comme la réponse de @FellowMD ne fonctionne pas sur les navigateurs modernes en raison de la dépréciation de createObjectURL, j'ai utilisé la même approche mais en utilisant l'attribut srcDoc d'iframe.

  1. Récupérer le contenu à afficher dans l'iframe en utilisant XMLHttpRequest ou toute autre méthode.
  2. Définir le paramètre srcdoc de l'iframe

Veuillez trouver ci-dessous un exemple React (je sais que c'est exagéré) :

import React, {useEffect, useState} from 'react';

function App() {
  const [content, setContent] = useState('');

  useEffect(() => {
    // Fetch the content using the method of your choice
    const fetchedContent = '<h1>Some HTML</h1>';
    setContent(fetchedContent);
  }, []);

  return (
    <div className="App">
      <iframe sandbox id="inlineFrameExample"
              title="Inline Frame Example"
              width="300"
              height="200"
              srcDoc={content}>
      </iframe>

    </div>
  );
}

export default App;

Srcdoc est maintenant supporté par la plupart des navigateurs. Il semble que Edge ait eu un peu de retard pour l'implémenter : https://caniuse.com/#feat=iframe-srcdoc

3voto

tom Points 31

Il s'avère que URL.createObjectURL() est déprécié dans Chrome 71.
(voir https://developers.google.com/web/updates/2018/10/chrome-71-deps-rems )
En s'appuyant sur les excellentes réponses de @Niet the dark Absol et @FellowMD, voici comment charger un fichier dans un iframe, si vous devez passer des en-têtes d'authentification. (Vous ne pouvez pas simplement définir l'attribut src sur l'URL) :

$scope.load() {
    var iframe = #angular.element("#reportViewer");
    var url = "http://your.url.com/path/etc";
    var token = "your-long-auth-token";
    var headers = [['Authorization', 'Bearer ' + token]];
    $scope.populateIframe(iframe, url, headers);
}

$scope.populateIframe = function (iframe, url, headers) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url);
    xhr.onreadystatechange = handler;
    xhr.responseType = 'document';
    headers.forEach(function (header) {
        xhr.setRequestHeader(header[0], header[1]);
    });
    xhr.send();

    function handler() {
        if (this.readyState === this.DONE) {
            if (this.status === 200) {
                var content = iframe[0].contentWindow ||
                    iframe[0].contentDocument.document || 
                    iframe[0].contentDocument;
                content.document.open();
                content.document.write(this.response.documentElement.innerHTML);
                content.document.close();
            } else {
                iframe.attr('srcdoc', '<html><head></head><body>Error loading page.</body></html>');
            }
        }
    }
}

et un coup de chapeau à Courajs : https://github.com/courajs/pdf-poc/blob/master/script.js

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X