Is it possible to add Request Headers to an iframe src request?

后端 未结 4 1592
栀梦
栀梦 2020-12-02 09:52

I understand that you can set HTTP request headers very easily when making AJAX calls in JavaScript.

However is it also possible to set custom HTTP request headers w

相关标签:
4条回答
  • 2020-12-02 10:01

    No, you can't. However you could set the iframe source to some kind of preload script, which uses AJAX to fetch the actual page with all the headers you want.

    0 讨论(0)
  • 2020-12-02 10:02

    As @FellowMD answer is not working on modern browsers due to the depreciation of createObjectURL, I used the same approach but using iframe srcDoc attribute.

    1. Retrieve the content to display in the iframe using XMLHttpRequest or any other method
    2. Set the srcdoc parameter of the iframe

    Please find below a React example (I know it is overkill):

    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 is now supported on most browsers. It seems that Edge was a bit late to implement it: https://caniuse.com/#feat=iframe-srcdoc

    0 讨论(0)
  • 2020-12-02 10:11

    You can make the request in javascript, setting any headers you'd like. Then you can URL.createObjectURL(), to get something suitable for the src of the 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 :(');
        }
      }
    }
    

    The MIME type of the response is preserved. So if you get an html response, the html will show in the iframe. If you requested a pdf, the browser pdf viewer will kick in for the iframe.

    If this is part of a long-lived client-side app, you may want to use URL.revokeObjectURL() to avoid memory leaks.

    The object URLs are also pretty interesting. They're of the form blob:https://your.domain/1e8def13-3817-4eab-ad8a-160923995170. You can actually open them in a new tab and see the response, and they're discarded when the context that created them is closed.

    Here's a full example: https://github.com/courajs/pdf-poc

    0 讨论(0)
  • 2020-12-02 10:11

    It turns out that URL.createObjectURL() is deprecated in Chrome 71
    (see https://developers.google.com/web/updates/2018/10/chrome-71-deps-rems)
    Building on @Niet the dark Absol and @FellowMD's excellent answers, here's how to load a file into an iframe, if you need to pass in authentication headers. (You can't just set the src attribute to the 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>');
                }
            }
        }
    }
    

    and shoutout to courajs: https://github.com/courajs/pdf-poc/blob/master/script.js

    0 讨论(0)
提交回复
热议问题