javascript 更改 iframe src 时如何设置自定义 http 标头?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17694807/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to set custom http headers when changing iframe src?
提问by dave
Is there a way to add a custom http header into the request done by an <iframe>
when changing the source (src) using javascript?
有没有办法在<iframe>
使用javascript更改源(src)时将自定义http标头添加到由an完成的请求中?
采纳答案by Matthew Graves
You can have the results of an ajax request that has custom headers be set as the content of an iframe like so:
您可以将具有自定义标头的 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))
}
});
This is assuming the iframe is pointing at a cross domain src. It is simpler if everything is on the same domain.
这是假设 iframe 指向跨域 src。如果一切都在同一个域中,那就更简单了。
Edit: Maybe try this variation.
编辑:也许试试这个变体。
$.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);
}
});
回答by FellowMD
Rather than using a data URI, or setting the contents to a string, you can use URL.createObjectURL()
, and set it as the src
of the iframe.
您可以使用URL.createObjectURL()
, 并将其设置为src
iframe 的,而不是使用数据 URI 或将内容设置为字符串。
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 :(');
}
}
}
The object URLs are 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.
对象 URL 非常有趣。他们的形式blob:https://your.domain/1e8def13-3817-4eab-ad8a-160923995170
。您实际上可以在新选项卡中打开它们并查看响应,当创建它们的上下文关闭时,它们将被丢弃。
Here's a full example: https://github.com/courajs/pdf-poc
这是一个完整的例子:https: //github.com/courajs/pdf-poc
回答by Jono Job
I ended up going with the approach proposed by the other answers here, that use ajax to get the html string and then directly set the contents of the iFrame
.
我最终采用了此处其他答案提出的方法,即使用 ajax 获取 html 字符串,然后直接设置iFrame
.
However, I used the approach posted in this answerto actually set the contents of the iFrame
, as I found it worked well cross platform with almost all devices I could dig up.
但是,我使用此答案中发布的方法来实际设置iFrame
.
Tested - successful:
测试 - 成功:
- Chrome 54 (desktop) ^
- Firefox 49 (desktop) ^
- IE 11 (desktop) ^
- IE 10 (desktop) in emulation mode ^
- Safari/Chrome on iOS 8 (ipad)
- Chrome on Android 6 (nexus phone)
- Edge on Lumia 950 (Win 10 Phone)
- Chrome 54(桌面)^
- 火狐 49(桌面)^
- IE 11(桌面)^
- 模拟模式下的 IE 10(桌面)^
- iOS 8 (ipad) 上的 Safari/Chrome
- Android 6 上的 Chrome(nexus 手机)
- Lumia 950 上的 Edge(Win 10 手机)
^ confirmed that linked css and js in the content run correctly (others not tested)
^ 确认内容中链接的 css 和 js 运行正确(其他未测试)
Tested - unsuccessful:
测试 - 不成功:
- IE 9 (desktop) in emulation mode
- Safari/Chrome on iOS 7 (iPhone)
- 模拟模式下的 IE 9(桌面)
- iOS 7 (iPhone) 上的 Safari/Chrome
So putting them together gives something like this (Note: I havn't actually run this exact code):
所以把它们放在一起给出了这样的东西(注意:我实际上并没有运行这个确切的代码):
$.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();
}
});
Here's an example of setting the iFrame
contents in this JS Bin
下面是设置这个 JS Bin 中的iFrame
内容的例子
Edit:Here's the html part
编辑:这是 html 部分
<iframe id="myiframe" src="about:blank"></iframe>
Edit 2:
编辑2:
The solution above appears to no longer be working in Firefox (50.1.0) for some unknown reason. Using the solution in this answerI've now changed to code to the example below, which also seems to be more robust:
由于某些未知原因,上述解决方案似乎不再适用于 Firefox (50.1.0)。使用此答案中的解决方案,我现在已更改为以下示例的代码,这似乎也更加健壮:
$.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"]';
}
});
回答by dave
The following code works. It is a modification of the code provided by Matthew Graves, modified to use the srcdoc
attribute to solve the problem of CSS and JavaScript references not been ran. Unfortunately, it is only working in Chrome.
以下代码有效。它是对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)
}
});
Edit: Finally, I have resolved the issue of the scripts blocks cross-browser, by reassigning them to the iframe on document.ready function:
编辑:最后,我通过将它们重新分配给 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();
});
}
});