【发布时间】:2013-07-17 08:28:12
【问题描述】:
有没有办法在使用 javascript 更改源 (src) 时将自定义 http 标头添加到由 <iframe> 完成的请求中?
【问题讨论】:
标签: javascript iframe httprequest
有没有办法在使用 javascript 更改源 (src) 时将自定义 http 标头添加到由 <iframe> 完成的请求中?
【问题讨论】:
标签: javascript iframe httprequest
您可以将具有自定义标头的 ajax 请求的结果设置为 iframe 的内容,如下所示:
$.ajax({
type: "GET",
url: "https://app.icontact.com/icp/a/",
contentType: "application/json",
beforeSend: function(xhr, settings){
xhr.setRequestHeader("some_custom_header", "foo");},
success: function(data){
$("#output_iframe_id").attr('src',"data:text/html;charset=utf-8," + escape(data))
}
});
这是假设 iframe 指向一个跨域 src。如果一切都在同一个域上,那就更简单了。
编辑:也许试试这个变化。
$.ajax({
type: "GET",
url: "https://app.icontact.com/icp/a/",
contentType: "application/json",
beforeSend: function(xhr, settings){
xhr.setRequestHeader("some_custom_header", "foo");},
success: function(data){
$("#output_iframe_id").attr('src',"/")
$("#output_iframe_id").contents().find('html').html(data);
}
});
【讨论】:
可以使用URL.createObjectURL(),而不是使用数据URI,或者将内容设置为字符串,并将其设置为iframe的src。
var xhr = new XMLHttpRequest();
xhr.open('GET', 'some.pdf');
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 :(');
}
}
}
对象 URL 非常有趣。它们的形式为blob:https://your.domain/1e8def13-3817-4eab-ad8a-160923995170。实际上,您可以在新选项卡中打开它们并查看响应,当创建它们的上下文关闭时它们会被丢弃。
这是一个完整的例子:https://github.com/courajs/pdf-poc
【讨论】:
我最终采用了此处其他答案提出的方法,即使用 ajax 获取 html 字符串,然后直接设置 iFrame 的内容。
但是,我使用answer 中发布的方法来实际设置iFrame 的内容,因为我发现它在几乎所有我可以挖掘的设备上都能很好地跨平台运行。
测试 - 成功:
^确认内容中链接的css和js运行正常(其他未测试)
测试 - 不成功:
所以把它们放在一起会得到这样的结果(注意:我实际上并没有运行这个确切的代码):
$.ajax({
type: "GET",
url: "https://yourdomain.com/gethtml",
beforeSend: function(xhr) {
xhr.setRequestHeader("yourheader", "value");
},
success: function(data) {
var iframeDoc = document.querySelector('#myiframe').contentWindow.document;
iframeDoc.open('text/html', 'replace');
iframeDoc.write(data);
iframeDoc.close();
}
});
这里是设置iFrame内容in this JS Bin的示例
编辑:这是html部分
<iframe id="myiframe" src="about:blank"></iframe>
编辑 2:
由于某种未知原因,上述解决方案似乎不再适用于 Firefox (50.1.0)。使用answer 中的解决方案,我现在已将代码更改为以下示例,这似乎也更健壮:
$.ajax({
type: "GET",
url: "https://yourdomain.com/gethtml",
beforeSend: function(xhr) {
xhr.setRequestHeader("yourheader", "value");
},
success: function(data) {
var iframe = document.getElementById('myiframe');
iframe.contentWindow.contents = data;
iframe.src = 'javascript:window["contents"]';
}
});
【讨论】:
iFrame 的src?我只是将其保留为about:blank。
以下代码有效。是对code provided by Matthew Graves的修改,修改为使用srcdoc属性来解决CSS和JavaScript引用不跑的问题。不幸的是,它只适用于 Chrome。
$.ajax({
type: "GET",
url: "https://app.icontact.com/icp/a/",
contentType: "application/json",
beforeSend: function(xhr, settings){
xhr.setRequestHeader("some_custom_header", "foo");},
success: function(data){
$("#output_iframe_id").attr('srcdoc',data)
}
});
编辑:最后,我已经解决了跨浏览器的脚本块问题,方法是将它们重新分配给 document.ready 函数上的 iframe:
$(document).ready(function () {
var doc = $(document);
if (frames.length > 0) {
doc = frames[0].document;
$(doc).find('script').each(function () {
var script = document.createElement("script");
if ($(this).attr("type") != null) script.type = $(this).attr("type");
if ($(this).attr("src") != null) script.src = $(this).attr("src");
script.text = $(this).html();
$(doc).find('head')[0].appendChild(script);
$(this).remove();
});
}
});
【讨论】: