47

Is there a way to add a custom http header into the request done by an <iframe> when changing the source (src) using javascript?

4

4 回答 4

34

您可以将具有自定义标头的 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); 
    }
});
于 2013-07-17T08:39:37.333 回答
17

URL.createObjectURL()您可以使用, 并将其设置为srciframe的,而不是使用数据 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 :(');
    }
  }
}

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

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

于 2017-02-16T16:56:47.757 回答
7

我最终采用了此处其他答案提出的方法,即使用 ajax 获取 html 字符串,然后直接设置iFrame.

但是,我使用此答案中发布的方法来实际设置iFrame.

测试 - 成功:

  • 铬 54(桌面)^
  • Firefox 49(桌面)^
  • IE 11(桌面)^
  • 仿真模式下的 IE 10(桌面)^
  • iOS 8 (ipad) 上的 Safari/Chrome
  • Android 6 上的 Chrome(Nexus 手机)
  • Lumia 950 上的 Edge(Win 10 手机)

^ 确认内容中链接的css和js运行正常(其他未测试)

测试 - 不成功:

  • 仿真模式下的 IE 9(桌面)
  • iOS 7 (iPhone) 上的 Safari/Chrome

所以把它们放在一起会得到这样的结果(注意:我实际上并没有运行这个确切的代码):

$.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();
    }
});

下面是一个在这个 JS BiniFrame中设置内容的例子

编辑:这是html部分

<iframe id="myiframe" src="about:blank"></iframe>

编辑2:

由于某种未知原因,上述解决方案似乎不再适用于 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"]';
    }
});
于 2016-11-16T03:13:44.330 回答
5

以下代码有效。它是对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();
        });
    }
});
于 2013-07-19T12:22:36.443 回答