【问题标题】:How to set custom http headers when changing iframe src?更改 iframe src 时如何设置自定义 http 标头?
【发布时间】:2013-07-17 08:28:12
【问题描述】:

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

【问题讨论】:

    标签: javascript iframe httprequest


    【解决方案1】:

    您可以将具有自定义标头的 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); 
        }
    });
    

    【讨论】:

    • 非常感谢!顺便问一下,如果在同一个域中,有什么区别?
    • 它不适用于 IE :-S。在 Chrome 和 Firefox 中有效,但外部文件(在框架内引用)的 css 规则和脚本未应用。
    • 试一试
    • 好多了!我在twigstechtips.blogspot.com.es/2011/02/… 遇到了那个解决方案@ 有机会添加脚本块吗?因为这样做时它们不包括在内。谢谢!
    • 这很奇怪,因为如果我在 chrome 中检查生成的 html 代码,将 url 分配给 'src' 属性(没有 http 自定义标头)和执行 $("#output_iframe_id") 之间没有区别。内容().find('html').html(数据);但后者不执行 或外部文件上定义的 javascript 函数。但是它执行 document.onready() 函数。
    【解决方案2】:

    可以使用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

    【讨论】:

    • 如果 URL 对象可用,这似乎是最佳答案。否则降级为接受的答案。
    【解决方案3】:

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

    但是,我使用answer 中发布的方法来实际设置iFrame 的内容,因为我发现它在几乎所有我可以挖掘的设备上都能很好地跨平台运行。

    测试 - 成功:

    • Chrome 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();
        }
    });
    

    这里是设置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"]';
        }
    });
    

    【讨论】:

    • 不幸的是,如果您使用“应用内”的相对路径加载某些内容,您可能会遇到问题。用 angular2 试了一下,发现路由问题“找不到路由”……还没有找到任何答案。
    • @eatmypants 不知道你遇到了什么 - 我没有玩过 angular2,但我在 angular1 中使用它。由于对服务器的调用是 ajax,因此您应该能够以任何其他 ajax 调用的方式解析您的 url。您是否正在编辑iFramesrc?我只是将其保留为about:blank
    【解决方案4】:

    以下代码有效。是对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();
            });
        }
    });
    

    【讨论】:

      猜你喜欢
      • 2020-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-21
      • 1970-01-01
      相关资源
      最近更新 更多