web-dev-qa-db-ja.com

iframe srcを変更するときにカスタムhttpヘッダーを設定するにはどうすればよいですか?

Javascriptを使用してソース(src)を変更するときに、<iframe>によって実行されるリクエストにカスタムhttpヘッダーを追加する方法はありますか?

36
dave

カスタムヘッダーを持つ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); 
    }
});
31
Matthew Graves

データURIを使用したり、コンテンツを文字列に設定したりする代わりに、 URL.createObjectURL() を使用して、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

10
FellowMD

次のコードが機能します。これは 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:最後に、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();
        });
    }
});
5
dave

私はここで他の回答で提案されたアプローチに行きました。これは、ajaxを使用してhtml文字列を取得し、iFrameの内容を直接設定します。

ただし、この answer に投稿されたアプローチを使用して、iFrameの内容を実際に設定しました。掘り出す。

テスト済み-成功:

  • Chrome 54(デスクトップ)^
  • Firefox 49(デスクトップ)^
  • IE 11(デスクトップ)^
  • エミュレーションモードのIE 10(デスクトップ)^
  • IOS 8のSafari/Chrome(ipad)
  • Chrome on Android 6(nexus phone)
  • Lumia 950のエッジ(Win 10 Phone)

^コンテンツ内のリンクされた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 BinでiFrameコンテンツ を設定する例を次に示します

編集:ここに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"]';
    }
});
5
Jono Job