更改iframe src时如何设置自定义http标头?

dav*_*ave 36 javascript iframe httprequest

有没有办法在<iframe>使用javascript更改源(src)时为自己完成的请求添加自定义http标头?

Mat*_*ves 31

您可以将包含自定义标头的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))
    }
});
Run Code Online (Sandbox Code Playgroud)

这是假设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); 
    }
});
Run Code Online (Sandbox Code Playgroud)

  • 它不适用于 IE :-S。在 Chrome 和 Firefox 中工作,但不应用来自外部文件(在框架内引用)的 css 规则和脚本。 (2认同)
  • 这很奇怪,因为如果我在 chrome 中检查生成的 html 代码,将 url(没有 http 自定义标头)分配给 'src' 属性和执行 $("#output_iframe_id").contents().find('html ').html(数据); 但后者不执行 &lt;head&gt; 或外部文件上定义的 javascript 函数。但是它执行 document.onready() 函数。 (2认同)

Fel*_*wMD 10

您可以使用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 :(');
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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


dav*_*ave 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)
        }
    });
Run Code Online (Sandbox Code Playgroud)

编辑:最后,我通过将脚本块重新分配给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();
        });
    }
});
Run Code Online (Sandbox Code Playgroud)


Jon*_*Job 5

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

但是,我使用了这个答案中发布的方法来实际设置内容iFrame,因为我发现它与几乎所有我可以挖掘的设备在跨平台上运行良好.

经过测试 - 成功:

  • Chrome 54(桌面)^
  • Firefox 49(桌面)^
  • IE 11(桌面)^
  • IE 10(桌面)处于仿真模式^
  • iOS 8上的Safari/Chrome(ipad)
  • Android 6上的Chrome(nexus手机)
  • Edge on Lumia 950(赢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();
    }
});
Run Code Online (Sandbox Code Playgroud)

这是在此JS Bin中设置iFrame内容的示例

编辑:这是html部分

<iframe id="myiframe" src="about:blank"></iframe>
Run Code Online (Sandbox Code Playgroud)

编辑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"]';
    }
});
Run Code Online (Sandbox Code Playgroud)