是否可以将请求标头添加到 iframe src 请求?
Posted
技术标签:
【中文标题】是否可以将请求标头添加到 iframe src 请求?【英文标题】:Is it possible to add Request Headers to an iframe src request? 【发布时间】:2012-11-06 03:16:35 【问题描述】:我了解到,在 javascript 中进行 AJAX 调用时,您可以非常轻松地设置 HTTP 请求标头。
但是,在通过脚本将 iframe 插入页面时,是否也可以设置自定义 HTTP 请求标头?
<iframe src="someURL"> <!-- is there any place to set headers in this? -->
【问题讨论】:
【参考方案1】:您可以在 javascript 中发出请求,设置您喜欢的任何标头。然后你可以URL.createObjectURL()
,得到适合iframe的src
的东西。
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
【讨论】:
完美。完美地工作。谢谢。 你这个人!我正在开发一个受此代码启发的 Angular 5 组件,以在 Angularjs 中显示 pdf 预览。这对我帮助很大 @BSSchwarzkopf 看起来你是对的。 Edge 支持 Blob URL,但它们在 iframe 的 src 属性中不起作用。我认为它违反了规范:“这个方案应该能够与 Web API 一起使用......以及设计用于 HTTP URL 的元素......一般来说,这个方案应该被设计为可以在 Web 上使用 URL 的任何地方使用。”边缘跟踪器问题:developer.microsoft.com/en-us/microsoft-edge/platform/issues/… 规范:w3.org/TR/FileAPI/#use-cases-scheme 我得到“无法在 'URL' 上执行 'createObjectURL':找不到与提供的签名匹配的函数。”在 Chrome 84.0.4147.105 上。 @poiuytrez 这意味着您传递了错误的参数。它需要文件、Blob 或 MediaSource。也许你传递的是 null、undefined、promise 或 Request 对象?【参考方案2】:不,你不能。但是,您可以将 iframe
源设置为某种预加载脚本,该脚本使用 AJAX 来获取包含您想要的所有标题的实际页面。
【讨论】:
Hi Niet,能否提供 JSFiddle 中的示例实现代码 我相信 Niet 的意思是这样的 ***.com/a/17695034/1524918 这样的预加载脚本中的请求会不会被发送到不同的域,从而违反同源策略? 默认发送哪些标头?这有什么标准吗?【参考方案3】:由于 createObjectURL 的贬值,@FellowMD 的答案不适用于现代浏览器,因此我使用了相同的方法,但使用了 iframe srcDoc 属性。
-
使用 XMLHttpRequest 或任何其他方法检索要在 iframe 中显示的内容
设置iframe的srcdoc参数
请在下面找到一个 React 示例(我知道这是矫枉过正):
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"
srcDoc=content>
</iframe>
</div>
);
export default App;
现在大多数浏览器都支持 Srcdoc。看来Edge实现有点晚了:https://caniuse.com/#feat=iframe-srcdoc
【讨论】:
createObjectURL
仅在 MediaStream 参数中被弃用。不推荐传递 Blob,实际上是 sees pretty wide and increasing usage。不过,我很感激为保持最新状态所做的努力:)
@poiuytrez 当我想获取带有自定义标头的内容时,我收到this question 中询问的错误,请您看一下
这个解决方案没有展示如何在请求中设置headers来获取内容【参考方案4】:
事实证明 URL.createObjectURL() 在 Chrome 71 中已被弃用 (见https://developers.google.com/web/updates/2018/10/chrome-71-deps-rems) 在 @Niet the dark Absol 和 @FellowMD 的出色答案的基础上,如果您需要传入身份验证标头,这里是如何将文件加载到 iframe 中。 (您不能只将 src 属性设置为 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>');
向 courajs 大喊:https://github.com/courajs/pdf-poc/blob/master/script.js
【讨论】:
来自 Google 链接:“URL.createObjectURL() 方法已从 MediaStream 接口中删除。”这种影响 MediaStream 接口的弃用是否与其他答案相关? (我认为不会。) 不推荐使用。仅从 MediaStream 中删除 @TheMaster 这确实是文档所说的,但我花了几个小时试图让它工作但没有成功。它无法推测原因。上面显示的代码是我编写代码时最终运行的代码,我没有足够的带宽再试一次。 您可以将该方法用于 Blob 对象。在你的情况下,就像URL.createObjectURL(new Blob([this.response.documentElement.innerHTML]))
createObjectURL
仅在 MediaStream 参数中被弃用。不推荐传递 Blob,实际上是 sees pretty wide and increasing usage。不过,我很感激为保持最新状态所做的努力:)以上是关于是否可以将请求标头添加到 iframe src 请求?的主要内容,如果未能解决你的问题,请参考以下文章