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.