iframe src 요청에 요청 헤더를 추가 할 수 있습니까?


83

JavaScript에서 AJAX 호출을 할 때 HTTP 요청 헤더를 매우 쉽게 설정할 수 있음을 이해합니다.

그러나 스크립트를 통해 iframe을 페이지에 삽입 할 때 사용자 지정 HTTP 요청 헤더를 설정할 수도 있습니까?

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

답변:


31

아니, 할 수 없습니다. 그러나 iframeAJAX를 사용하여 원하는 모든 헤더가있는 실제 페이지를 가져 오는 일종의 사전로드 스크립트로 소스를 설정할 수 있습니다.


4
안녕하세요 NIET, 당신은 JSFiddle에 샘플 구현 코드를 제공 주실 래요
— 나빈 레디에게

나는 Niet이 다음과 같은 것을 의미한다고 믿는다. stackoverflow.com/a/17695034/1524918
— Ryan Kara

5
이러한 사전로드 스크립트의 요청이 다른 도메인으로 전송되어 동일한 출처 정책을 위반하지 않습니까?
— mart1n

기본적으로 어떤 헤더가 전송됩니까? 그것에 대한 표준이 있습니까?
— Fund Monica의 소송

74

원하는 헤더를 설정하여 자바 스크립트로 요청할 수 있습니다. 그런 다음 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

너 그쪽이야! 이 코드에서 영감을 얻은 Angular 5 구성 요소를 작업 중입니다. 이 크게 도움이되었습니다
— FireDragon

감사합니다! 당신은 내 생명을 구했습니다!
— Renato Souza de Oliveira

1
@BSSchwarzkopf 당신이 옳은 것 같습니다. Blob URL은 Edge에서 지원되지만 iframe의 src 속성에서는 작동하지 않습니다. "이 스키마는 웹 API와 함께 사용할 수 있어야하며 ... HTTP URL과 함께 사용하도록 설계된 요소와 함께 사용할 수 있어야합니다. 일반적으로이 스키마는 다음과 같이 설계되어야합니다. 웹에서 URL을 사용할 수있는 모든 곳에서 사용할 수 있습니다. " Edge 추적기 문제 : developer.microsoft.com/en-us/microsoft-edge/platform/issues/… 사양 : w3.org/TR/FileAPI/#use-cases-scheme
— FellowMD

" 'URL'에서 'createObjectURL'실행 실패 : 제공된 서명과 일치하는 기능을 찾을 수 없습니다."라는 메시지가 나타납니다. Chrome 84.0.4147.105에서.
— poiuytrez

3

그것은 URL.createObjectURL ()가 크롬 71에서 더 이상 사용되지 않습니다 것으로 나타났다
(참조 https://developers.google.com/web/updates/2018/10/chrome-71-deps-rems를 )
Absol @Niet에 어두운 건물 및 @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 인터페이스에 영향을 미치는이 지원 중단이 다른 답변과 관련이 있습니까? (나는 그렇게 생각하지 것이다.)
— 자레드 써 스크에게

더 이상 사용되지 않습니다. MediaStream만이에서 제거
— 마스터

1
@TheMaster는 실제로 문서에 나와있는 내용이지만 작동하도록 몇 시간을 보냈지 만 성공하지 못했습니다. 이유를 추측 할 수 없습니다. 위에 표시된 코드는 내가 코드를 작성했을 때 작동하게 된 것이며 다시 시도 할 대역폭이 없습니다.
— TomEberhard

이 메서드를 Blob 개체와 함께 사용할 수 있습니다. 귀하의 경우에는URL.createObjectURL(new Blob([this.response.documentElement.innerHTML]))
— u.unver34

createObjectURLMediaStream 인수에 대해서만 지원이 중단됩니다. Blob을 전달하는 것은 더 이상 사용되지 않으며 실제로 상당히 광범위하고 사용량이 증가합니다 . 그래도 최신 상태로 유지하려는 노력에 감사드립니다 :)
— FellowMD

2

@FellowMD 답변은 createObjectURL의 감가 상각으로 인해 최신 브라우저에서 작동하지 않으므로 동일한 접근 방식을 사용했지만 iframe srcDoc 속성을 사용했습니다.

  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을 전달하는 것은 더 이상 사용되지 않으며 실제로 상당히 광범위하고 사용량이 증가합니다 . 그래도 최신 상태로 유지하려는 노력에 감사드립니다. :)
— FellowMD
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.