prosource

프레임 src가 로드되지 않으면 오류가 발생합니다. 오류: "'http://www.google.co.in/' '을 프레임에 표시하는 것을 거부했습니다."

probook 2023. 9. 20. 20:24
반응형

프레임 src가 로드되지 않으면 오류가 발생합니다. 오류: "'http://www.google.co.in/' '을 프레임에 표시하는 것을 거부했습니다."

사용중입니다Knockout.jssrc 구성 tag능).

이제 사용자가 http://www.google.com 을 구성한 경우(iframe에서 로드되지 않는다는 것을 알고 있으므로 -ve 시나리오에 사용하고 있습니다) IFrame에 표시해야 하지만 오류가 발생합니다:-

'http://www.google.co.in/' '이 'X-Frame-Options'를 'SAMEORIGIN'으로 설정했기 때문에 프레임 표시를 거부했습니다.

Iframe의 코드는 다음과 같습니다.

<iframe class="iframe" id="iframe" data-bind="attr: {src: externalAppUrl, height: iframeheight}">
    <p>Hi, This website does not supports IFrame</p>
</iframe>

제가 원하는 것은 URL이 로딩되지 않을 경우 입니다.사용자 지정 메시지를 표시합니다.Screenshot of console when I get error 여기를 만지작거리다

이제 on load 및 on error를 다음과 같이 사용할 경우:-

<iframe id="browse" style="width:100%;height:100%" onload="alert('Done')" onerror="alert('Failed')"></iframe>

w3schools.com 을 로드하면 잘 작동하지만 google.com 에서는 작동하지 않습니다.

두 번째:- 제가 기능적으로 만들어 본 것처럼 시도하면 작동이 안 됩니다.

<iframe id="browse" style="width:100%;height:100%" onload="load" onerror="error"></iframe>

어떻게 실행해서 오류를 포착해야 할지 모르겠습니다.

편집:- 스택 오버플로우에서 iframe이 로드되지 않거나 로드되지 않는 경우 함수를 호출하는 것을 보았지만 iframe에서 로드할 수 있는 사이트에 대한 오류가 표시됩니다.

또한 스택 오버플로우 iframe on load 이벤트도 알아봤습니다 감사합니다!!

브라우저에서 설정한 동일한 오리진 정책 때문에 클라이언트 측에서 이 작업을 수행할 수 없습니다.당신은 아이프레임의 폭과 높이와 같은 기본적인 특성 외에 많은 정보를 얻을 수 없을 것입니다.

또한 구글은 응답 헤더에 SAMEORIGIN의 'X-Frame-Options'를 설정합니다.

브라우저가 동일 오리진 정책을 적용하기 때문에 구글에 아약스 호출을 했더라도 응답을 검사할 수 없습니다.

따라서 서버에서 요청하여 I 프레임에 사이트를 표시할 수 있는지 확인하는 것이 유일한 방법입니다.

그래서, 당신의 서버에..웹 앱에서 www.google.com 에 요청을 한 다음 응답을 검사하여 X-Frame-Options의 헤더 인수가 있는지 확인합니다.존재하는 경우 IFrame이 오류가 발생한다는 것을 알 수 있습니다.

iframe의 이벤트를 바인딩할 수 있다고 생각합니다. iframe 콘텐츠가 완전히 로딩되면 이벤트가 발생합니다.

setTimeout을 시작할 수 있는 동시에 iFrame이 로드되면 타임아웃이 발생하도록 합니다.

코드:

var iframeError;

function change() {
    var url = $("#addr").val();
    $("#browse").attr("src", url);
    iframeError = setTimeout(error, 5000);
}

function load(e) {
    alert(e);
}

function error() {
    alert('error');
}

$(document).ready(function () {
    $('#browse').on('load', (function () {
        load('ok');
        clearTimeout(iframeError);
    }));

});

데모: http://jsfiddle.net/IrvinDominin/QXc6P/

두번째문제

인라인 함수 호출에서 부모를 놓쳤기 때문입니다. 다음을 변경해 보십시오.

<iframe id="browse" style="width:100%;height:100%" onload="load" onerror="error"></iframe>

다음 항목으로 이동합니다.

<iframe id="browse" style="width:100%;height:100%" onload="load('Done func');" onerror="error('failed function');"></iframe>

데모: http://jsfiddle.net/IrvinDominin/ALBXR/4/

온로드는 항상 트리거가 될 것입니다. 이 문제는 시도 캐치 블록을 사용하는 것이 좋습니다.문서 내용을 가져오려고 하면 예외가 발생합니다.

iframe.onload = function(){
   var that = $(this)[0];
   try{
        that.contentDocument;
   }
   catch(err){
        //TODO 
   }
}

이것은 Edens의 답변을 약간 수정한 것입니다 - 크롬에 있는 저는 오류를 감지하지 못했습니다.콘솔에서 "'X-Frame-Options'를 'same origin'으로 설정했기 때문에 'https://www.google.ca/' '을 프레임에 표시하는 것을 거부했습니다."라는 오류가 계속 표시됩니다.적어도 이것은 에러 메시지를 잡을 것이고 그리고 나서 당신은 그것을 처리할 수 있습니다.

 <iframe id="myframe" src="https://google.ca"></iframe>

 <script>
 myframe.onload = function(){
 var that = document.getElementById('myframe');

 try{
    (that.contentWindow||that.contentDocument).location.href;
 }
 catch(err){
    //err:SecurityError: Blocked a frame with origin "http://*********" from accessing a cross-origin frame.
    console.log('err:'+err);
}
}
</script>

로 해결했습니다.window.length. 그러나 이 솔루션을 사용하면 현재 오류(X-Frame 또는 404)를 제거할 수 있습니다.

iframe.onload = event => {
   const isLoaded = event.target.contentWindow.window.length // 0 or 1
}

MSDN

업데이트: contentWindow.name 은 이제 origin 프레임 간에 항상 오류를 발생시킵니다.현재로서는 이 서버 쪽을 하는 방법밖에 없는 것 같습니다.원격 apis용 헤더를 캡처하기 위해 작은 클라우드 플레어 작업자를 작성했으며 여기서 X-Frame-Options를 확인하는 데 사용할 수 있습니다.

iframe에서 렌더링하기 전에 확인해야 할 샘플 코드: (jsfiddle: https://jsfiddle.net/2gud39aw/2/)

function checkUrlFrameOptions(apiurl){
  return fetch("https://header-inspector.repalash.workers.dev/?" + new URLSearchParams({
    'apiurl': apiurl,
    'headers': 'x-frame-options'
  }), {
    method: 'GET'
  }).then(r => r.json()).then(json => {
    let xFrameOp = (json.headers['x-frame-options'] || '').toLowerCase();
    // deny all requests
    if(xFrameOp==='deny') return false;
    // deny if different origin
    if(xFrameOp==='sameorigin' && json.origin !== location.origin) return false;
    return true;
  })
}

checkUrlFrameOptions("https://google.com").then((res)=>console.log("google.com can be loaded in iframe: ", res))
checkUrlFrameOptions("https://example.com").then((res)=>console.log("example.com can be loaded in iframe: ", res))

Cloudflare worker endpoint(https://header-inspector.repalash.workers.dev)는 테스트용일 뿐이므로 프로덕션에 사용하지 마십시오.이 코드는 https://gist.github.com/repalash/b1e778dbe3ac2e7149831c530a6535f9 에서 사용할 수 있으며 클라우드 플레어 작업자로 직접 배포할 수 있습니다.

Old Answer

Chrome과 Safari에서 테스트한 간단한 해결책이 있습니다.

    const iframe = document.createElement('iframe')
    iframe.onload = function() {
        try {
            iframe.contentWindow.name
        } catch (e) {
            if (e.message.includes('cross-origin')) console.warn(e.message);
            else console.error(e.message);
        }
    }

    iframe.src = "https://google.com";

jsFiddle 데모: https://jsfiddle.net/k5e1mg3t/5/

저도 비슷한 문제에 직면했습니다.온로드 핸들러를 사용하지 않고 해결했습니다.AngularJs 프로젝트를 진행하고 있어서 $interval과 $timeout을 사용했습니다.setTimeout 및 setInterval을 사용할 수도 있습니다.코드는 다음과 같습니다.

 var stopPolling;
 var doIframePolling;
 $scope.showIframe = true;
 doIframePolling = $interval(function () {
    if(document.getElementById('UrlIframe') && document.getElementById('UrlIframe').contentDocument.head && document.getElementById('UrlIframe').contentDocument.head.innerHTML != ''){
        $interval.cancel(doIframePolling);
        doIframePolling = undefined;
        $timeout.cancel(stopPolling);
        stopPolling = undefined;
        $scope.showIframe = true;
    }
},400);

stopPolling = $timeout(function () {
        $interval.cancel(doIframePolling);
        doIframePolling = undefined;
        $timeout.cancel(stopPolling);
        stopPolling = undefined;
        $scope.showIframe = false;     
},5000);

 $scope.$on("$destroy",function() {
        $timeout.cancel(stopPolling);
        $interval.cancel(doIframePolling);
 });

0.4초마다 iFrame Document의 머리 부분을 계속 확인합니다.저는 뭔가 있습니다.CORS 오류로 빈 페이지가 표시되어 CORS에서 로딩이 중지되지 않았습니다.5초 후에도 아무것도 없는 경우 오류(Cors policy) 등이 발생했습니다.적합한 메시지를 표시합니다.감사해요.당신의 문제가 해결되길 바랍니다.

수락된 답변에서 설명된 것처럼 https://stackoverflow.com/a/18665488/4038790, 당신은 서버를 통해 확인해야 합니다.

브라우저에서 이를 확인할 수 있는 확실한 방법이 없기 때문에 iframe을 통해 URL을 로드할 수 있는지 확인할 수 있는 빠른 서버 엔드포인트를 직접 구축하는 것이 좋습니다.이면 쿼리 을 url하여 url url록다 AJAX할 수 됩니다.url(또는 서버가 원하는 것이 무엇이든 간에) 의 서버 과 같습니다NodeJs의 서버 코드는 다음과 같습니다.

const express = require('express')
const app = express()

app.get('/checkCanLoadIframeUrl', (req, res) => {
  const request = require('request')
  const Q = require('q')

  return Q.Promise((resolve) => {
    const url = decodeURIComponent(req.query.url)

    const deafultTimeout = setTimeout(() => {
      // Default to false if no response after 10 seconds
      resolve(false)
    }, 10000)

    request({
        url,
        jar: true /** Maintain cookies through redirects */
      })
      .on('response', (remoteRes) => {
        const opts = (remoteRes.headers['x-frame-options'] || '').toLowerCase()
        resolve(!opts || (opts !== 'deny' && opts !== 'sameorigin'))
        clearTimeout(deafultTimeout)
      })
      .on('error', function() {
        resolve(false)
        clearTimeout(deafultTimeout)
      })
  }).then((result) => {
    return res.status(200).json(!!result)
  })
})

app.listen(process.env.PORT || 3100)

언급URL : https://stackoverflow.com/questions/15273042/catch-error-if-iframe-src-fails-to-load-error-refused-to-display-http-ww

반응형