यदि iframe src लोड करने में विफल रहता है तो त्रुटि पकड़ें। त्रुटि: - "फ्रेम में 'http://www.google.co.in/' प्रदर्शित करने से इनकार .."


79

मैं Knockout.jsiframe srcटैग को बांधने के लिए उपयोग कर रहा हूं (यह उपयोगकर्ता के संबंध में कॉन्फ़िगर करने योग्य होगा)।

अब, यदि उपयोगकर्ता ने http://www.google.com को कॉन्फ़िगर किया है (मुझे पता है कि यह iframe में लोड नहीं होगा, तो यही कारण है कि मैं इसे -ve परिदृश्य के लिए उपयोग कर रहा हूं) और जिसे IFrame में दिखाया जाना है। लेकिन यह त्रुटि फेंकता है: -

फ्रेम में ' http://www.google.co.in/ ' प्रदर्शित करने से इनकार कर दिया क्योंकि यह 'SAMEORIGIN' के लिए 'X- फ़्रेम-विकल्प' सेट करता है।

इफ्रेम के लिए मेरे पास निम्नलिखित कोड है: -

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

यदि मैं चाहता हूं कि यदि URL लोड नहीं हो पाता है। मैं कस्टम संदेश प्रदर्शित करना चाहता हूं । त्रुटि मिलने पर कंसोल का स्क्रीनशॉट यहाँ क्लिक करें

अब, अगर मैं onload और onerror का उपयोग करता हूं: -

<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 में लोड किया जा सकता है।

इसके अलावा, मैं भार घटना पर Stackoverflow iframe में देखा है धन्यवाद !!

जवाबों:


44

आप ब्राउज़र द्वारा निर्धारित समान उत्पत्ति नीति के कारण ग्राहक की ओर से ऐसा नहीं कर पाएंगे । आप इसकी चौड़ाई और ऊंचाई जैसी बुनियादी गुणों के अलावा iFrame से अधिक जानकारी प्राप्त करने में सक्षम नहीं होंगे।

इसके अलावा, Google अपने प्रतिक्रिया शीर्षलेख में SAMEORIGIN का एक ' X- फ्रेम-विकल्प ' सेट करता है।

यहां तक ​​कि अगर आपने Google को एक अजाक्स कॉल किया था तो आप प्रतिक्रिया का निरीक्षण करने में सक्षम नहीं होंगे क्योंकि ब्राउज़र समान उत्पत्ति नीति लागू करता है।

तो, एकमात्र विकल्प यह है कि आप अपने सर्वर से अनुरोध करें कि क्या आप अपने आइफ्रेम में साइट प्रदर्शित कर सकते हैं।

इसलिए, आपके सर्वर पर .. आपका वेब ऐप www.google.com से अनुरोध करेगा और फिर यह देखने के लिए प्रतिक्रिया का निरीक्षण करेगा कि उसमें X- फ्रेम-ऑप्शंस का हेडर तर्क है या नहीं। यदि यह मौजूद है तो आपको पता है कि IFrame त्रुटि करेगा।


रॉबेल iframeयह पता लगाने के लिए एक चाल का उपयोग करता है कि क्या खेल को <iframe src="roblox-player:foo">कस्टम यूआरआई हैंडलर का पता लगाकर स्थापित किया गया है। इस iframeविफलता का पता लगाने के लिए "डाउनलोड" बटन दिखाई देता है। फिर वे इसे कैसे करते हैं?
tresf

1
@QZ समर्थन मुझे पता नहीं है कि आपकी क्या बात है।
इवान लार्सन

1
@EvanLarsen मैं एक बहुत लोकप्रिय वीडियो गेम का उल्लेख कर रहा हूं जो सफलतापूर्वक <iframe>लॉन्च करने के लिए तकनीक का उपयोग करता है (और मैं उम्मीद कर रहा था) ओएस में पंजीकृत एक यूआरआई हैंडलर। यह एक मुफ्त गेम है, आप इसे स्थापित कर सकते हैं और अपने लिए देख सकते हैं। जब आप ब्राउज़र के माध्यम से गेम में शामिल होते हैं, तो यह गेम लॉन्च करने के लिए एक iframe हैक का उपयोग करता है। यदि यह विफल रहता है, तो वे "डाउनलोड" बटन दिखाते हैं। किसी तरह वे जानते हैं कि यूआरआई को ठीक से संभाला गया था या नहीं। मेरा प्रारंभिक अनुमान iframeत्रुटि को पकड़ रहा था , लेकिन उत्तर (साथ ही मेरे परीक्षण) यह सुझाव देते हैं कि यह संभव नहीं है। जब आइफ्रेम विफल रहता है तो उन्हें कैसे पता चलेगा?
1

यह सिर्फ एक अनुमान है लेकिन मुझे यकीन है कि वेबसाइट सिर्फ आपके स्थानीय मशीन पर एक स्व-होस्ट किए गए वेब ऐप को बुला रही है। यदि कॉल विफल हो जाता है तो यह डाउनलोड बटन दिखाता है। एक बार जब आप गेम को अपनी मशीन पर डाउनलोड और इंस्टॉल कर लेंगे तो वेबसाइट स्थानीय स्व-होस्टेड वेब ऐप को कॉल कर सकेगी। सेल्फ होस्टेड वेब ऐप के द्वारा .. मेरा मतलब सिर्फ http एंड पॉइंट्स वाला ऐप है जिसे किसी भी वेबसाइट द्वारा कॉल किया जा सकता है जो इसके बारे में जानता है। (यानी; लोकलहोस्ट: 7845 / ऑपेंज़्म / रूम / 2534 )
इवान लार्सन

localhost:7845काफी धारणा है। सबसे पहले, यह मिश्रित सामग्री चेतावनियों / त्रुटियों (roblox.com HTTPS का उपयोग करता है) और अगले, टकराव के मामले में विफलता बंदरगाहों की आवश्यकता होगी। सॉफ्टवेयर लॉन्च करने के लिए इस्तेमाल की जाने वाली तकनीक ए है iframe। यह पृष्ठ स्रोत की जांच करके देखा जा सकता है। किसी तरह जब यह सॉफ्टवेयर लॉन्च करने में विफल रहता है, तो वे इसका पता लगाने में सक्षम होते हैं। यह ब्राउज़र ट्रैकर आईडी का उपयोग करके "फोन होम" + टाइमआउट विधि के माध्यम से किया जा सकता है। मैं इसका उल्लेख करता हूं क्योंकि यह iframeविफलता का पता लगाने से संबंधित एप्लिकेशन लॉन्च करने के लिए उपयोगी है, लेकिन केवल अगर विफलता का पता लगाया जा सकता है।
tresf 5

15

मुझे लगता है कि आप loadiframe की घटना को बांध सकते हैं, घटना तब होती है जब iframe सामग्री पूरी तरह से लोड हो जाती है।

उसी समय आप एक सेटटाइमआउट शुरू कर सकते हैं, यदि 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/


51
अरे, बस बेला पर देखा - यह एक त्रुटि फेंक कभी नहीं है।
vvohra87

12
मैं उबंटू और क्रोम पर हूं - कोई फर्क नहीं पड़ता कि मैं टेक्स्ट बॉक्स में क्या
उर डालती

3
@IrvinDomininakaEdward: दोनों फिडेल लिंक काम नहीं कर रहा है ... यह नहीं खुल रहा है ... क्या आपने फ़िडल को हटा दिया है?
हितेश

10
माइनस 1 क्योंकि राज्य के ऊपर टिप्पणी के रूप में: फिफ़र कभी भी अपेक्षित त्रुटि संदेश नहीं फेंकता है जब iframe लोड करने में विफल रहता है। इसका कारण यह है कि iframe की लोड घटना तब भी होती है जब वह सामग्री को लोड नहीं करती है।
कोडतोड

3
यह चयनित उत्तर नहीं होना चाहिए। नीचे ईवान द्वारा सही है: ब्राउज़र सुरक्षा यह पता लगाने से रोकती है।
स्कॉट स्मिथ

9

ओनलोड हमेशा ट्रिगर रहेगा, मैं इस समस्या का उपयोग करता हूं, कोशिश करें कि आप कैच ब्लॉक को पकड़ें। यह एक अपवाद फेंक देगा जब आप कंटेंट रिमूवल प्राप्त करने की कोशिश करेंगे।

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

1
यह अब तक का सबसे सरल तरीका है और यह वास्तव में भी काम करता है!
साइमन जैक्सन

15
यह भी क्रॉस डोमेन के लिए काम नहीं करता है - यह किसी भी तरह से एक त्रुटि फेंक देगा
Luoruize

यह मेरे लिए, मेरे अपने डोमेन के iframe के लिए काम करता है। X- फ़्रेम-विकल्प: SAMEORIGIN
रयान

मेरे लिए यह समान अपवाद फेंकता है जब भी iframe ने सामग्री लोड की। आपको कैसे पता चलेगा कि सामग्री लोड नहीं हुई है?
लीकोडर

मैं जवाब देने वाला था कि इस तरह से उस त्रुटि को पकड़ना संभव है! लेकिन आपने पहले ही कर दिया! मैं उसी सटीक मुद्दे को संभाल रहा हूं (और यह भी जांचने के लिए कि क्या उपयोगकर्ता को मेरे डोमेन में एक निश्चित पृष्ठ पर पुनर्निर्देशित किया गया था) इस तरह से! मुझे यह सवाल "आइफ्रेम में त्रुटियों से निपटने" के लिए खोज रहा था, लेकिन मैं अब आइफ्रेम के अंदर 503 त्रुटि का सामना कर रहा हूं!
सम्पगुन

8

यह एडेंस जवाब के लिए एक मामूली संशोधन है - जो क्रोम में मेरे लिए त्रुटि को पकड़ नहीं पाया। हालाँकि आपको अभी भी कंसोल में एक त्रुटि मिलेगी: " फ्रेम में ' 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>

यह परिणाम "के लिए रिक्त स्थान की संपत्ति 'स्थान को नहीं पढ़ सकता है" that.contentDocumentऔर कई कार्यशील साइटें अभी भी that.contentWindowलोडिंग प्रक्रिया के दौरान एक त्रुटि को फेंक देंगी ।
कार्ट

1

मुझे इसी तरह की समस्या का सामना करना पड़ा। मैंने इसे ऑनलोड हैंडलर का उपयोग किए बिना हल किया। मैं AngularJs प्रोजेक्ट पर काम कर रहा था इसलिए मैंने $ अंतराल और $ टाइमआउट का उपयोग किया। यू भी सेटटाइमआउट और सेटइंटरवल का उपयोग कर सकते हैं। आपके कोड:

 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 दस्तावेज़ के प्रमुख की जाँच करते रहते हैं। I somthing is present। कोडिंग द्वारा बंद नहीं किया गया था क्योंकि CORS त्रुटि रिक्त पृष्ठ दिखाती है। यदि 5 सेकंड के बाद कुछ भी मौजूद नहीं है तो कुछ त्रुटि थी (कोर्स पॉलिसी) आदि। उपयुक्त संदेश दिखाएं। धन्यवाद। मुझे आशा है कि यह आपकी समस्या को हल करेगा।


2
Uncaught DOMException: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame with origin "..." from accessing a cross-origin frame.- क्या आप सुनिश्चित हैं कि यह क्रॉस-डोमेन काम कर रहा है?
मंगल

0

मैं एक ही समस्या है, iframe src लोड त्रुटि होने पर क्रोम फायरर पर फायर नहीं कर सकता।

लेकिन मेरे मामले में, मुझे बस एक क्रॉस डोमेन http अनुरोध करने की आवश्यकता है, इसलिए मैं iffame के बजाय स्क्रिप्ट src / onload / onerror का उपयोग करता हूं। यह अच्छा काम कर रहा है।


0

मैंने इसे हल किया window.length। लेकिन इस समाधान के साथ आप वर्तमान त्रुटि (एक्स-फ्रेम या 404) ले सकते हैं।

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

MSDN


0

जैसा कि स्वीकृत उत्तर में बताया गया है, https://stackoverflow.com/a/18665488/4038790 , आपको एक सर्वर के माध्यम से जांचना होगा।

क्योंकि ब्राउज़र में इसे जांचने का कोई विश्वसनीय तरीका नहीं है, मेरा सुझाव है कि आप अपने आप को एक त्वरित सर्वर समापन बिंदु बनाएँ जिसका उपयोग आप यह जांचने के लिए कर सकते हैं कि क्या कोई url iframe के माध्यम से लोड होने योग्य है। एक बार जब आपका सर्वर उठ रहा है और चल रहा है, तो बस क्वेरी स्ट्रिंग url(या जो भी आपके सर्वर की इच्छा हो) में यूआरएल प्रदान करके किसी भी यूआरएल की जांच करने के लिए इसे एक AJAX अनुरोध भेजें । यहाँ 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)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.