关于javascript:是否可以将请求标头添加到iframe src请求?

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

我了解您可以在JavaScript中进行AJAX调用时非常轻松地设置HTTP请求标头。

但是,通过脚本将iframe插入页面时,是否还可以设置自定义HTTP请求标头?

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

您可以使用javascript发出请求,设置所需的任何标题。然后,您可以URL.createObjectURL(),以获得适用于iframe的src的内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 :(');
    }
  }
}

响应的MIME类型被保留。因此,如果您收到html响应,则html将显示在iframe中。如果您请求pdf,则浏览器pdf查看器将加入iframe。

如果这是长期存在的客户端应用程序的一部分,则可能需要使用URL.revokeObjectURL()以避免内存泄漏。

对象URL也很有趣。它们的格式为blob:https://your.domain/1e8def13-3817-4eab-ad8a-160923995170。实际上,您可以在新选项卡中打开它们并查看响应,并且在关闭创建它们的上下文时它们将被丢弃。

这是一个完整的示例:https://github.com/courajs/pdf-poc


不,你不能。但是,您可以将iframe源设置为某种预加载脚本,该脚本使用AJAX来获取包含所有所需标题的实际页面。


原来,Chrome 71不推荐使用URL.createObjectURL()
(请参阅https://developers.google.com/web/updates/2018/10/chrome-71-deps-rems)

在@Niet上建立黑暗的Absol和@FellowMD的出色答案,如果需要传递身份验证标头,以下是将文件加载到iframe中的方法。 (您不能只将src属性设置为URL):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
$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>');
            }
        }
    }
}

并向courajs大喊:https://github.com/courajs/pdf-poc/blob/master/script.js


由于createObjectURL的贬值,@ FellowMD答案在现代浏览器上不起作用,因此我使用了相同的方法,但使用了iframe srcDoc属性。

  • 使用XMLHttpRequest或任何其他方法检索要在iframe中显示的内容
  • 设置iframe的srcdoc参数
  • 请在下面找到一个React示例(我知道这太过分了):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    import React, {useEffect, useState} from 'react';

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


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


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


       
      );
    }

    export default App;

    现在大多数浏览器都支持Srcdoc。似乎Edge实施起来有点晚了:https://caniuse.com/#feat=iframe-srcdoc