リクエストヘッダーをiframesrcリクエストに追加することは可能ですか?


83

JavaScriptでAJAX呼び出しを行うときに、HTTPリクエストヘッダーを非常に簡単に設定できることを理解しています。

ただし、スクリプトを介してiframeをページに挿入するときにカスタムHTTPリクエストヘッダーを設定することもできますか?

<iframe src="someURL"> <!-- is there any place to set headers in this? -->

回答:


31

いいえ、できません。ただし、iframeソースをある種のプリロードスクリプトに設定することもできます。このスクリプトは、AJAXを使用して、必要なすべてのヘッダーを含む実際のページをフェッチします。


4
こんにちはニート、JSFiddleでサンプル実装コードを提供していただけますか
Naveen Reddy


5
このようなプリロードスクリプトのリクエストは別のドメインに送信されるため、同一生成元ポリシーに違反しませんか?
mart1n 2015

デフォルトで送信されるヘッダーは何ですか?その基準はありますか?
モニカの訴訟に資金を提供する

74

必要なヘッダーを設定して、JavaScriptでリクエストを行うことができます。次に、iframeにURL.createObjectURL()適したものを取得できますsrc

var xhr = new XMLHttpRequest();

xhr.open('GET', 'page.html');
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 :(');
    }
  }
}

応答のMIMEタイプは保持されます。したがって、html応答を受け取ると、htmlはiframeに表示されます。PDFをリクエストした場合は、ブラウザのPDFビューアがiframeを起動します。

これが長期間有効なクライアント側アプリの一部である場合は、URL.revokeObjectURL()メモリリークを回避するために使用することをお勧めします。

オブジェクトのURLも非常に興味深いものです。それらは形式blob:https://your.domain/1e8def13-3817-4eab-ad8a-160923995170です。実際にそれらを新しいタブで開いて応答を確認することができ、それらを作成したコンテキストが閉じられると、それらは破棄されます。

完全な例は次のとおりです:https//github.com/courajs/pdf-poc


完璧です。完璧に動作しました。ありがとうございました。
mike123 2017

あなたは男だ!AngularjsでPDFプレビューを表示するために、このコードに触発されたAngular5コンポーネントに取り組んでいます。これは非常に私を助けている
FireDragon

ありがとうございました!あなたは私の命を救いました!
Renato Souza de Oliveira

1
@BSSchwarzkopfはあなたが正しいように見えます。Blob URLはEdgeでサポートされていますが、iframeのsrc属性では機能しません。これは仕様に違反していると思います。「このスキームは、WebAPIで使用できる必要があります...およびHTTPURLで使用するように設計された要素で使用できる必要があります...一般に、このスキームは次のように設計する必要があります。 Web上でURLを使用できる場所ならどこでも使用できます。」エッジトラッカーの問題:developer.microsoft.com/en-us/microsoft-edge/platform/issues/…仕様:w3.org/TR/FileAPI/#use-cases-scheme
FellowMD

「「URL」で「createObjectURL」を実行できませんでした:提供された署名に一致する関数が見つかりませんでした」というメッセージが表示されます。Chrome84.0.4147.105で。
poiuytrez

3

URL.createObjectURL()はChrome 71では非推奨であることが判明しました(https://developers.google.com/web/updates/2018/10/chrome-71-deps-remsを
参照) @Niet the darkAbsolと@FellowMDの優れた回答です。認証ヘッダーを渡す必要がある場合に、ファイルをiframeにロードする方法は次のとおりです。(src属性をURLに設定するだけでは不十分です):

$scope.load() {
    var iframe = #angular.element("#reportViewer");
    var url = "http://your.url.com/path/etc";
    var token = "your-long-auth-token";
    var headers = [['Authorization', 'Bearer ' + token]];
    $scope.populateIframe(iframe, url, headers);
}

$scope.populateIframe = function (iframe, url, headers) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url);
    xhr.onreadystatechange = handler;
    xhr.responseType = 'document';
    headers.forEach(function (header) {
        xhr.setRequestHeader(header[0], header[1]);
    });
    xhr.send();

    function handler() {
        if (this.readyState === this.DONE) {
            if (this.status === 200) {
                var content = iframe[0].contentWindow ||
                    iframe[0].contentDocument.document || 
                    iframe[0].contentDocument;
                content.document.open();
                content.document.write(this.response.documentElement.innerHTML);
                content.document.close();
            } else {
                iframe.attr('srcdoc', '<html><head></head><body>Error loading page.</body></html>');
            }
        }
    }
}

そしてcourajsに叫ぶ:https//github.com/courajs/pdf-poc/blob/master/script.js


1
Googleリンクから:「URL.createObjectURL()メソッドはMediaStreamインターフェースから削除されました。」MediaStreamインターフェースに影響を与えるこの非推奨は、他の回答に関連していますか?(私はそうは思わないでしょう。)
JaredThirsk20年

非推奨ではありません。MediaStreamのから削除のみ
ザ・マスター

1
@TheMasterは確かにドキュメントに書かれていることですが、私はそれを機能させるために数時間を費やし、成功しませんでした。理由を推測することはできません。上記のコードは、コーディングした時点で機能していたものであり、再試行するための帯域幅がありません。
TomEberhard

そのメソッドはBlobオブジェクトで使用できます。あなたの場合は次のようになりますURL.createObjectURL(new Blob([this.response.documentElement.innerHTML]))
u.unver34 2010年

createObjectURLMediaStream引数についてのみ非推奨になっています。Blobを渡すこと非推奨ではなく、実際、かなり広く、使用量が増えています。私は物事を最新に保つ努力に感謝します:)
FellowMD20年

2

createObjectURLの減価償却により、@ FellowMDの回答が最新のブラウザーで機能しないため、同じアプローチを使用しましたが、iframesrcDoc属性を使用しました。

  1. XMLHttpRequestまたはその他のメソッドを使用して、iframeに表示するコンテンツを取得します
  2. iframeのsrcdocパラメータを設定します

以下のReactの例をご覧ください(私はそれがやり過ぎだと知っています):

import React, {useEffect, useState} from 'react';

function App() {
  const [content, setContent] = useState('');


  useEffect(() => {
    // Fetch the content using the method of your choice
    const fetchedContent = '<h1>Some HTML</h1>';
    setContent(fetchedContent);
  }, []);


  return (
    <div className="App">
      <iframe sandbox id="inlineFrameExample"
              title="Inline Frame Example"
              width="300"
              height="200"
              srcDoc={content}>
      </iframe>


    </div>
  );
}

export default App;

Srcdocは現在ほとんどのブラウザでサポートされています。Edgeはそれを実装するのに少し遅れたようです:https//caniuse.com/#feat=iframe-srcdoc


createObjectURLMediaStream引数についてのみ非推奨になっています。Blobを渡すこと非推奨ではなく、実際、かなり広く、使用量が増えています。私は物事を最新に保つ努力に感謝します:)
FellowMD20年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.