Controlled Frame

Demián Renzulli
Demián Renzulli
Simon Hangl
Simon Hangl

आम तौर पर, <iframe> एलिमेंट का इस्तेमाल, ब्राउज़िंग कॉन्टेक्स्ट में बाहरी संसाधनों को एम्बेड करने के लिए किया जाता है. iframe, वेब की सुरक्षा नीतियों को लागू करते हैं. इसके लिए, वे क्रॉस-ऑरिजिन से एम्बेड किए गए कॉन्टेंट को होस्ट पेज से अलग करते हैं. साथ ही, होस्ट पेज को क्रॉस-ऑरिजिन से एम्बेड किए गए कॉन्टेंट से अलग करते हैं. इस तरीके से, ऑरिजिन के बीच सुरक्षित सीमा तय करके सुरक्षा को बेहतर बनाया जाता है. हालांकि, इससे इस्तेमाल के कुछ उदाहरणों पर असर पड़ता है. उदाहरण के लिए, उपयोगकर्ताओं को अलग-अलग सोर्स से कॉन्टेंट को डाइनैमिक तरीके से लोड और मैनेज करने की ज़रूरत पड़ सकती है. जैसे, कोई शिक्षक क्लासरूम की स्क्रीन पर वेबपेज दिखाने के लिए, नेविगेशन इवेंट ट्रिगर करता है. हालांकि, कई वेबसाइटें X-Frame-Options और कॉन्टेंट की सुरक्षा नीति (सीएसपी) जैसे सुरक्षा हेडर का इस्तेमाल करके, iframe में एम्बेड करने की सुविधा को साफ़ तौर पर ब्लॉक करती हैं. इसके अलावा, iframe से जुड़ी पाबंदियों की वजह से, एम्बेड किए गए पेज, एम्बेड किए गए कॉन्टेंट के नेविगेशन या व्यवहार को सीधे तौर पर मैनेज नहीं कर पाते.

Controlled Frame API इस समस्या को हल करता है. इसकी मदद से, किसी भी वेब कॉन्टेंट को लोड किया जा सकता है. भले ही, एंबेड करने से जुड़ी पाबंदियों वाली नीतियां लागू हों. यह एपीआई, सिर्फ़ आइसोलेटेड वेब ऐप्लिकेशन (आईडब्ल्यूए) में उपलब्ध है. इनमें सुरक्षा से जुड़े अतिरिक्त तरीके शामिल होते हैं, ताकि उपयोगकर्ताओं और डेवलपर, दोनों को संभावित जोखिमों से बचाया जा सके.

Controlled Frames API लागू करना

कंट्रोल किए गए फ़्रेम का इस्तेमाल करने से पहले, आपको काम करने वाला आईडब्ल्यूए सेट अप करना होगा. इसके बाद, अपने पेजों में कंट्रोल किए गए फ़्रेम इंटिग्रेट किए जा सकते हैं.

अनुमति से जुड़ी नीति जोड़ना

Controlled Frames API का इस्तेमाल करने के लिए, इससे जुड़ी अनुमति चालू करें. इसके लिए, अपने आईडब्ल्यूए मेनिफ़ेस्ट में permissions_policy फ़ील्ड जोड़ें और उसकी वैल्यू "controlled-frame" पर सेट करें. इसके अलावा, इसमें cross-origin-isolated कुंजी भी शामिल है. यह कुंजी, Controlled Frames API के लिए खास तौर पर नहीं बनाई गई है. हालांकि, सभी आईडब्ल्यूए के लिए इसकी ज़रूरत होती है. इससे यह तय होता है कि दस्तावेज़, उन एपीआई को ऐक्सेस कर सकता है जिनके लिए क्रॉस-ऑरिजिन आइसोलेशन की ज़रूरत होती है.

{
   ...
  "permissions_policy": {
     ...
     "controlled-frame": ["self"],
     "cross-origin-isolated": ["self"]
     ...
  }
   ...
}

आइसोलेटेड वेब ऐप्लिकेशन (आईडब्ल्यूए) के मेनिफ़ेस्ट में मौजूद controlled-frame कुंजी, अनुमतियों की नीति के लिए अनुमति वाली सूची तय करती है. इससे यह तय किया जाता है कि कौनसे ऑरिजिन, Controlled Frame API का इस्तेमाल कर सकते हैं. मेनिफ़ेस्ट, Permissions Policy के पूरे सिंटैक्स के साथ काम करता है. इससे *, खास ऑरिजिन या self और src जैसे कीवर्ड जैसी वैल्यू इस्तेमाल की जा सकती हैं. हालांकि, यह ध्यान रखना ज़रूरी है कि IWA से जुड़े एपीआई, अन्य ऑरिजिन को नहीं सौंपे जा सकते. अगर अनुमति वाली सूची में वाइल्डकार्ड या बाहरी ऑरिजिन शामिल हैं, तब भी ये अनुमतियां controlled-frame जैसी IWA सुविधाओं के लिए लागू नहीं होंगी. स्टैंडर्ड वेब ऐप्लिकेशन के उलट, IWAs में नीति के तहत कंट्रोल की जाने वाली सभी सुविधाएं डिफ़ॉल्ट रूप से बंद होती हैं. इसलिए, इनके बारे में साफ़ तौर पर जानकारी देना ज़रूरी होता है. IWA से जुड़ी सुविधाओं के लिए, इसका मतलब है कि सिर्फ़ self (IWA का अपना ऑरिजिन) या src (एम्बेड किए गए फ़्रेम का ऑरिजिन) जैसी वैल्यू काम करती हैं.

कंट्रोल किया गया फ़्रेम एलिमेंट जोड़ना

अपने आईडब्ल्यूए में तीसरे पक्ष का कॉन्टेंट एम्बेड करने के लिए, अपने एचटीएमएल में <controlledframe> एलिमेंट डालें.

<controlledframe id="controlledframe_1" src="https://example.com">
</controlledframe>

partition एट्रिब्यूट का इस्तेमाल करके, एम्बेड किए गए कॉन्टेंट के लिए स्टोरेज पार्टिशनिंग को कॉन्फ़िगर किया जाता है. इससे आपको कुकी और लोकल स्टोरेज जैसे डेटा को अलग करने में मदद मिलती है, ताकि डेटा को सभी सेशन में सेव रखा जा सके.

उदाहरण: मेमोरी में मौजूद स्टोरेज पार्टीशन

"session1" नाम के इन-मेमोरी स्टोरेज पार्टीशन का इस्तेमाल करके, कंट्रोल किया गया फ़्रेम बनाएं. इस पार्टीशन में सेव किया गया डेटा (जैसे, कुकी और localStorage) तब मिट जाएगा, जब फ़्रेम बंद हो जाएगा या ऐप्लिकेशन का सेशन खत्म हो जाएगा.

<controlledframe id="controlledframe_1" src="https://example.com">
</controlledframe>

उदाहरण: स्थायी स्टोरेज पार्टीशन

"user_data" नाम वाले परसिस्टेंट स्टोरेज पार्टीशन का इस्तेमाल करके, कंट्रोल किया गया फ़्रेम बनाएं. "persist:" प्रीफ़िक्स यह पक्का करता है कि इस पार्टीशन में सेव किया गया डेटा डिस्क में सेव हो जाए. साथ ही, यह ऐप्लिकेशन के सभी सेशन में उपलब्ध रहेगा.

<controlledframe id="frame_2" src="..." partition="persist:user_data">
</controlledframe>

एलिमेंट का रेफ़रंस पाना

<controlledframe> एलिमेंट का रेफ़रंस पाएं, ताकि आप इसके साथ किसी भी स्टैंडर्ड एचटीएमएल एलिमेंट की तरह इंटरैक्ट कर सकें:

const controlledframe = document.getElementById('controlledframe_1');

बार-बार होने वाले काम और इस्तेमाल के उदाहरण

सामान्य नियम के तौर पर, अपनी ज़रूरतों को पूरा करने के लिए सबसे अच्छी टेक्नोलॉजी चुनें. साथ ही, बिना किसी वजह के जटिलता से बचें. पिछले कुछ सालों में, प्रोग्रेसिव वेब ऐप्लिकेशन (PWA) ने नेटिव ऐप्लिकेशन के साथ अंतर को कम किया है. इससे वेब पर बेहतर अनुभव मिल रहा है. अगर किसी वेब ऐप्लिकेशन को तीसरे पक्ष का कॉन्टेंट एम्बेड करना है, तो हमारा सुझाव है कि सबसे पहले <iframe> के सामान्य तरीके का इस्तेमाल करें. अगर iframe की क्षमताओं से ज़्यादा ज़रूरतें हैं, तो IWAs पर Controlled Frames का इस्तेमाल करना सबसे अच्छा विकल्प हो सकता है. इस्तेमाल के सामान्य उदाहरणों के बारे में यहां बताया गया है.

तीसरे पक्ष के वेब कॉन्टेंट को एम्बेड करना

कई ऐप्लिकेशन को अपने यूज़र इंटरफ़ेस में तीसरे पक्ष का कॉन्टेंट लोड करने और दिखाने की ज़रूरत होती है. हालांकि, जब एक से ज़्यादा वेब ऐप्लिकेशन के मालिक शामिल होते हैं, तो एम्बेड किए गए ऐप्लिकेशन के साथ यह एक सामान्य स्थिति होती है. ऐसे में, शुरू से आखिर तक एक जैसी नीतियां लागू करना मुश्किल हो जाता है. उदाहरण के लिए, सुरक्षा सेटिंग की वजह से, कोई पारंपरिक <iframe> कुछ तरह के कॉन्टेंट को एम्बेड नहीं कर सकता. भले ही, कारोबारों को ऐसा करने की ज़रूरत हो. <iframe> एलिमेंट के उलट, कंट्रोल किए गए फ़्रेम को इन पाबंदियों को बायपास करने के लिए डिज़ाइन किया गया है. इससे ऐप्लिकेशन, कॉन्टेंट को लोड और दिखा सकते हैं. भले ही, स्टैंडर्ड एम्बेडिंग को साफ़ तौर पर प्रतिबंधित किया गया हो.

उपयोग के उदाहरण

  • Classroom में प्रज़ेंटेशन: कोई शिक्षक, क्लासरूम में मौजूद टचस्क्रीन का इस्तेमाल करके, शिक्षा से जुड़े ऐसे संसाधनों के बीच स्विच करता है जो आम तौर पर iframe एम्बेडिंग को ब्लॉक कर देते हैं.
  • खुदरा दुकानों या मॉल में डिजिटल साइनेज: शॉपिंग मॉल का कियॉस्क, अलग-अलग स्टोर की वेबसाइटों पर साइकल करता है. कंट्रोल किए गए फ़्रेम यह पक्का करते हैं कि ये पेज सही तरीके से लोड हों. भले ही, वे एम्बेड करने पर पाबंदी लगाते हों.

कोड सैंपल

एम्बेड किए गए कॉन्टेंट को मैनेज करने के लिए, यहां दिए गए Controlled Frame API का इस्तेमाल किया जा सकता है.

नेविगेशन: Controlled Frame, एंबेड किए गए कॉन्टेंट के नेविगेशन और नेविगेशन इतिहास को प्रोग्राम के हिसाब से मैनेज और कंट्रोल करने के कई तरीके उपलब्ध कराते हैं.

src एट्रिब्यूट, फ़्रेम में दिखाए गए कॉन्टेंट का यूआरएल सेट करता है या उसे हासिल करता है. यह एचटीएमएल एट्रिब्यूट की तरह ही काम करता है.

controlledframe.src = "https://example.com";

back() तरीका, फ़्रेम के इतिहास में एक चरण पीछे जाता है. वापस किया गया प्रॉमिस, बूलियन में बदल जाता है. इससे पता चलता है कि नेविगेशन पूरा हुआ या नहीं.

document.getElementById('backBtn').addEventListener('click', () => {
controlledframe.back().then((success) => {
console.log(`Back navigation ${success ? 'succeeded' : 'failed'}`); }).catch((error) => {
   console.error('Error during back navigation:', error);
   });
});

forward() तरीका, फ़्रेम के इतिहास में एक चरण आगे बढ़ता है. वापस किया गया प्रॉमिस, बूलियन वैल्यू में बदल जाता है. इससे पता चलता है कि नेविगेशन पूरा हुआ या नहीं.

document.getElementById('forwardBtn').addEventListener('click', () => {
controlledframe.forward().then((success) => {
   console.log(`Forward navigation ${success ? 'succeeded' : 'failed'}`);
}).catch((error) => {
    console.error('Error during forward navigation:', error);
  });
});

reload() तरीके से, फ़्रेम में मौजूद मौजूदा पेज को फिर से लोड किया जाता है.

document.getElementById('reloadBtn').addEventListener('click', () => {
   controlledframe.reload();
});

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

  • loadstart: जब फ़्रेम में नेविगेशन शुरू होता है, तब यह इवेंट ट्रिगर होता है.
  • loadcommit: यह इवेंट तब ट्रिगर होता है, जब नेविगेशन के अनुरोध को प्रोसेस कर लिया जाता है और मुख्य दस्तावेज़ का कॉन्टेंट लोड होना शुरू हो जाता है.
  • contentload: यह इवेंट तब ट्रिगर होता है, जब मुख्य दस्तावेज़ और उसके ज़रूरी संसाधन लोड हो जाते हैं. यह DOMContentLoaded इवेंट की तरह ही होता है.
  • loadstop: यह इवेंट तब ट्रिगर होता है, जब पेज के सभी संसाधन (इसमें सबफ़्रेम और इमेज शामिल हैं) लोड हो जाते हैं.
  • loadabort: यह इवेंट तब ट्रिगर होता है, जब नेविगेशन को बंद कर दिया जाता है. जैसे, उपयोगकर्ता की कार्रवाई या किसी अन्य नेविगेशन के शुरू होने की वजह से.
  • loadredirect: यह इवेंट तब ट्रिगर होता है, जब नेविगेशन के दौरान सर्वर-साइड रीडायरेक्ट होता है.
controlledframe.addEventListener('loadstart', (event) => {
   console.log('Navigation started:', event.url);
   // Example: Show loading indicator
 });
controlledframe.addEventListener('loadcommit', (event) => {
   console.log('Navigation committed:', event.url);
 });
controlledframe.addEventListener('contentload', (event) => {
   console.log('Content loaded for:', controlledframe.src);
   // Example: Hide loading indicator, maybe run initial script
 });
controlledframe.addEventListener('loadstop', (event) => {
   console.log('All resources loaded for:', controlledframe.src);
 });
controlledframe.addEventListener('loadabort', (event) => {
   console.warn(`Navigation aborted: ${event.url}, Reason: ${event.detail.reason}`);
 });
controlledframe.addEventListener('loadredirect', (event) => {
   console.log(`Redirect detected: ${event.oldUrl} -> ${event.newUrl}`);
});

आपके पास, कंट्रोल किए गए फ़्रेम में लोड किए गए कॉन्टेंट से शुरू किए गए कुछ इंटरैक्शन या अनुरोधों की निगरानी करने और उन्हें रोकने का विकल्प भी होता है. जैसे, डायलॉग बॉक्स खोलने, अनुमतियों का अनुरोध करने या नई विंडो खोलने की कोशिशें.

  • dialog: यह इवेंट तब ट्रिगर होता है, जब एम्बेड किया गया कॉन्टेंट कोई डायलॉग बॉक्स (सूचना, पुष्टि करें, प्रॉम्प्ट) खोलने की कोशिश करता है. आपको जानकारी मिलती है और आपके पास जवाब देने का विकल्प होता है.
  • consolemessage: यह इवेंट तब ट्रिगर होता है, जब फ़्रेम में कंसोल पर कोई मैसेज लॉग किया जाता है.
  • permissionrequest: यह इवेंट तब ट्रिगर होता है, जब एंबेड किया गया कॉन्टेंट किसी अनुमति का अनुरोध करता है. उदाहरण के लिए, जियोलोकेशन और सूचनाएं. आपको अनुरोध की जानकारी मिलती है. इसके बाद, आपके पास अनुरोध को स्वीकार या अस्वीकार करने का विकल्प होता है.
  • newwindow: यह इवेंट तब ट्रिगर होता है, जब एम्बेड किया गया कॉन्टेंट कोई नई विंडो या टैब खोलने की कोशिश करता है. उदाहरण के लिए, window.open या target="_blank" वाला लिंक. आपको इसकी जानकारी मिलती है और आपके पास कार्रवाई को मैनेज करने या ब्लॉक करने का विकल्प होता है.
controlledframe.addEventListener('dialog', (event) => {
   console.log(Dialog opened: Type=${event.messageType}, Message=${event.messageText});
   // You will need to respond, e.g., event.dialog.ok() or .cancel()
 });

controlledframe.addEventListener('consolemessage', (event) => {
   console.log(Frame Console [${event.level}]: ${event.message});
 });

controlledframe.addEventListener('permissionrequest', (event) => {
   console.log(Permission requested: Type=${event.permission});
   // You must respond, e.g., event.request.allow() or .deny()
   console.warn('Permission request needs handling - Denying by default');
   if (event.request && event.request.deny) {
     event.request.deny();
   }
});

controlledframe.addEventListener('newwindow', (event) => {
   console.log(New window requested: URL=${event.targetUrl}, Name=${event.name});
   // Decide how to handle this, e.g., open in a new controlled frame and call event.window.attach(), ignore, or block
   console.warn('New window request needs handling - Blocking by default');
 });

स्टेट में बदलाव होने पर इवेंट भी ट्रिगर होते हैं. ये इवेंट, कंट्रोल किए गए फ़्रेम की रेंडरिंग की स्थिति में होने वाले बदलावों के बारे में सूचना देते हैं. जैसे, डाइमेंशन या ज़ूम लेवल में बदलाव.

  • sizechanged: यह इवेंट तब ट्रिगर होता है, जब फ़्रेम के कॉन्टेंट के डाइमेंशन बदलते हैं.
  • zoomchange: यह इवेंट तब ट्रिगर होता है, जब फ़्रेम के कॉन्टेंट का ज़ूम लेवल बदलता है.
controlledframe.addEventListener('sizechanged', (event) => {
  console.log(Frame size changed: Width=${event.width}, Height=${event.height});
});

controlledframe.addEventListener('zoomchange', (event) => {
  console.log(Frame zoom changed: Factor=${event.newZoomFactor});
});

स्टोरेज के तरीके: कंट्रोल किए गए फ़्रेम, फ़्रेम के पार्टीशन में सेव किए गए डेटा को मैनेज करने के लिए एपीआई उपलब्ध कराते हैं.

स्टोर किए गए सभी डेटा को हटाने के लिए, clearData() का इस्तेमाल करें. यह खास तौर पर, उपयोगकर्ता के सेशन के बाद फ़्रेम को रीसेट करने या यह पक्का करने के लिए उपयोगी है कि फ़्रेम में कोई डेटा मौजूद न हो. यह तरीका, एक प्रॉमिस दिखाता है. यह प्रॉमिस तब पूरा होता है, जब कार्रवाई पूरी हो जाती है. कॉन्फ़िगरेशन के वैकल्पिक विकल्प भी दिए जा सकते हैं:

  • types: स्ट्रिंग का एक ऐसा कलेक्शन जिसमें यह बताया जाता है कि किस तरह का डेटा मिटाना है. उदाहरण के लिए, ['cookies', 'localStorage', 'indexedDB']. अगर इसे शामिल नहीं किया जाता है, तो आम तौर पर लागू होने वाले सभी डेटा टाइप मिटा दिए जाते हैं.
  • options: इससे डेटा मिटाने की प्रोसेस को कंट्रोल किया जा सकता है. जैसे, सिर्फ़ उस डेटा को मिटाने के लिए, समयसीमा तय करना जिसे उस समय के बाद बनाया गया है. इसके लिए, since प्रॉपर्टी (epoch के बाद के मिलीसेकंड में टाइमस्टैंप) का इस्तेमाल करें.

उदाहरण: कंट्रोल किए गए फ़्रेम से जुड़ा सारा स्टोरेज मिटाना

function clearAllPartitionData() {
   console.log('Clearing all data for partition:', controlledframe.partition);
   controlledframe.clearData()
     .then(() => {
       console.log('Partition data cleared successfully.');
     })
     .catch((error) => {
       console.error('Error clearing partition data:', error);
     });
}

उदाहरण: सिर्फ़ उन कुकी और लोकल स्टोरेज को मिटाना जिन्हें पिछले एक घंटे में बनाया गया है

function clearRecentCookiesAndStorage() {
   const oneHourAgo = Date.now() - (60 * 60 * 1000);
   const dataTypesArray = ['cookies', 'localStorage'];
   const dataTypesToClearObject = {};
   for (const type of dataTypesArray) {
      dataTypesToClearObject[type] = true;
   }
   const clearOptions = { since: oneHourAgo };
   console.log(`Clearing ${dataTypesArray.join(', ')} since ${new    Date(oneHourAgo).toISOString()}`); controlledframe.clearData(clearOptions, dataTypesToClearObject) .then(() => {
   console.log('Specified partition data cleared successfully.');
}).catch((error) => {
   console.error('Error clearing specified partition data:', error);
});
}

तीसरे पक्ष के ऐप्लिकेशन को बढ़ाना या उनमें बदलाव करना

Controlled Frames, सिर्फ़ एंबेड करने के अलावा, एंबेड करने वाले आईडब्ल्यूए को तीसरे पक्ष के एंबेड किए गए वेब कॉन्टेंट को कंट्रोल करने के तरीके भी उपलब्ध कराते हैं. एम्बेड किए गए कॉन्टेंट में स्क्रिप्ट को लागू किया जा सकता है, नेटवर्क के अनुरोधों को रोका जा सकता है, और डिफ़ॉल्ट कॉन्टेक्स्ट मेन्यू को बदला जा सकता है. ये सभी काम, अलग और सुरक्षित माहौल में किए जा सकते हैं.

उपयोग के उदाहरण

  • तीसरे पक्ष की साइटों पर ब्रैंडिंग लागू करना: एम्बेड की गई वेबसाइटों में कस्टम सीएसएस और JavaScript इंजेक्ट करें, ताकि एक जैसी विज़ुअल थीम लागू की जा सके.
  • नेविगेशन और लिंक के काम करने के तरीके को सीमित करना: स्क्रिप्ट इंजेक्ट करके, कुछ <a> टैग के काम करने के तरीकों को रोकना या बंद करना.
  • क्रैश या इस्तेमाल न होने पर, अपने-आप ठीक होने की सुविधा: एम्बेड किए गए कॉन्टेंट की निगरानी करें, ताकि यह पता चल सके कि वह काम नहीं कर रहा है. जैसे, खाली स्क्रीन, स्क्रिप्ट से जुड़ी गड़बड़ियां. इसके अलावा, टाइम आउट होने के बाद, प्रोग्राम के हिसाब से सेशन को फिर से लोड करें या रीसेट करें.

कोड सैंपल

स्क्रिप्ट इंजेक्शन: कंट्रोल किए गए फ़्रेम में JavaScript इंजेक्ट करने के लिए, executeScript() का इस्तेमाल करें. इससे आपको व्यवहार को पसंद के मुताबिक बनाने, ओवरले जोड़ने या एम्बेड किए गए तीसरे पक्ष के पेजों से डेटा निकालने की सुविधा मिलती है. आपके पास स्ट्रिंग के तौर पर इनलाइन कोड देने का विकल्प होता है. इसके अलावा, एक या उससे ज़्यादा स्क्रिप्ट फ़ाइलों का रेफ़रंस दिया जा सकता है. इसके लिए, IWA पैकेज में रिलेटिव पाथ का इस्तेमाल करें. यह तरीका एक प्रॉमिस दिखाता है. यह प्रॉमिस, स्क्रिप्ट के एक्ज़ीक्यूशन के नतीजे के तौर पर रिज़ॉल्व होता है. आम तौर पर, यह आखिरी स्टेटमेंट की वैल्यू होती है.

document.getElementById('scriptBtn').addEventListener('click', () => {
   controlledframe.executeScript({
      code: `document.body.style.backgroundColor = 'lightblue';
             document.querySelectorAll('a').forEach(link =>    link.style.pointerEvents = 'none');
             document.title; // Return a value
            `,
      // You can also inject files:
      // files: ['./injected_script.js'],
}) .then((result) => {
   // The result of the last statement in the script is usually returned.
   console.log('Script execution successful. Result (e.g., page title):', result); }).catch((error) => {
   console.error('Script execution failed:', error);
   });
});

स्टाइल इंजेक्शन: कंट्रोल किए गए फ़्रेम में लोड किए गए पेजों पर कस्टम स्टाइल लागू करने के लिए, insertCSS() का इस्तेमाल करें.

document.getElementById('cssBtn').addEventListener('click', () => {
  controlledframe.insertCSS({
    code: `body { font-family: monospace; }`
    // You can also inject files:
    // files: ['./injected_styles.css']
  })
  .then(() => {
    console.log('CSS injection successful.');
  })
  .catch((error) => {
    console.error('CSS injection failed:', error);
  });
});

नेटवर्क अनुरोध को इंटरसेप्ट करना: WebRequest API का इस्तेमाल करके, एम्बेड किए गए पेज से नेटवर्क अनुरोधों को देखा जा सकता है. साथ ही, उनमें बदलाव भी किया जा सकता है. जैसे, अनुरोधों को ब्लॉक करना, हेडर में बदलाव करना या इस्तेमाल को लॉग करना.

// Get the request object
const webRequest = controlledframe.request;

// Create an interceptor for a specific URL pattern
const interceptor = webRequest.createWebRequestInterceptor({
  urlPatterns: ["*://evil.com/*"],
  blocking: true,
  includeHeaders: "all"
});

// Add a listener to block the request
interceptor.addEventListener("beforerequest", (event) => {
  console.log('Blocking request to:', event.url);
  event.preventDefault();
});

// Add a listener to modify request headers
interceptor.addEventListener("beforesendheaders", (event) => {
  console.log('Modifying headers for:', event.url);
  const newHeaders = new Headers(event.headers);
  newHeaders.append('X-Custom-Header', 'MyValue');
  event.setRequestHeaders(newHeaders);
});

कस्टम कॉन्टेक्स्ट मेन्यू जोड़ना: एम्बेड किए गए फ़्रेम में, राइट-क्लिक करने पर दिखने वाले कस्टम मेन्यू जोड़ने, हटाने, और मैनेज करने के लिए, contextMenus API का इस्तेमाल करें. इस उदाहरण में दिखाया गया है कि कंट्रोल किए गए फ़्रेम में, "चुने गए हिस्से को कॉपी करें" कस्टम मेन्यू को कैसे जोड़ा जाता है. इस इमेज में दिखाया गया है कि टेक्स्ट चुने जाने के बाद, उपयोगकर्ता के राइट क्लिक करने पर मेन्यू दिखता है. इस पर क्लिक करने से, चुना गया टेक्स्ट क्लिपबोर्ड पर कॉपी हो जाता है. इससे, एम्बेड किए गए कॉन्टेंट में आसानी से और उपयोगकर्ता के हिसाब से इंटरैक्शन किए जा सकते हैं.

const menuItemProperties = {
  id: "copy-selection",
  title: "Copy selection",
  contexts: ["selection"],
  documentURLPatterns: [new URLPattern({ hostname: '*.example.com'})]
};

// Create the context menu item using a promise
try {
  await controlledframe.contextMenus.create(menuItemProperties);
  console.log(`Context menu item "${menuItemProperties.id}" created successfully.`);
} catch (error) {
  console.error(`Failed to create context menu item:`, error);
}

// Add a standard event listener for the 'click' event
controlledframe.contextMenus.addEventListener('click', (event) => {
    if (event.menuItemId === "copy-selection" && event.selectionText) {
        navigator.clipboard.writeText(event.selectionText)
          .then(() => console.log("Text copied to clipboard."))
          .catch(err => console.error("Failed to copy text:", err));
    }
});

डेमो

Controlled Frame के तरीकों की खास जानकारी के लिए, Controlled Frame का डेमो देखें.

Controlled Frame API का डेमो

इसके अलावा, IWA Kitchen Sink में, कई टैब वाला एक ऐप्लिकेशन मौजूद है. हर टैब में, अलग-अलग IWA API के बारे में बताया गया है. जैसे, Controlled Frames, Direct Sockets वगैरह.

आईडब्ल्यूए किचन सिंक

नतीजा

Controlled Frames API की मदद से, आइसोलेटेड वेब ऐप्लिकेशन (आईडब्ल्यूए) में तीसरे पक्ष के वेब कॉन्टेंट को एम्बेड, एक्सटेंड, और उसके साथ इंटरैक्ट करने का सुरक्षित और बेहतर तरीका मिलता है. ये iframe की सीमाओं को दूर करते हैं. साथ ही, नई सुविधाएं उपलब्ध कराते हैं. जैसे, एम्बेड किए गए कॉन्टेंट में स्क्रिप्ट चलाना, नेटवर्क अनुरोधों को रोकना, और कस्टम कॉन्टेक्स्ट मेन्यू लागू करना. ये सभी काम, आइसोलेशन बाउंड्री को बनाए रखते हुए किए जाते हैं. हालांकि, इन एपीआई की मदद से एम्बेड किए गए कॉन्टेंट को बेहतर तरीके से कंट्रोल किया जा सकता है. इसलिए, इनके साथ सुरक्षा से जुड़ी कुछ अतिरिक्त शर्तें भी लागू होती हैं. साथ ही, ये सिर्फ़ आईडब्ल्यूए में उपलब्ध होते हैं. आईडब्ल्यूए को उपयोगकर्ताओं और डेवलपर, दोनों के लिए बेहतर सुरक्षा देने के मकसद से डिज़ाइन किया गया है. ज़्यादातर मामलों में, डेवलपर को सबसे पहले स्टैंडर्ड <iframe> एलिमेंट का इस्तेमाल करना चाहिए. ये एलिमेंट, कई मामलों में आसान और काफ़ी होते हैं. कंट्रोल किए गए फ़्रेम का इस्तेमाल तब किया जाना चाहिए, जब iframe पर आधारित समाधानों को एम्बेड करने से जुड़ी पाबंदियों की वजह से ब्लॉक कर दिया गया हो या उनमें ज़रूरी कंट्रोल और इंटरैक्शन की सुविधाएं न हों. चाहे आपको कियॉस्क मोड बनाना हो, तीसरे पक्ष के टूल इंटिग्रेट करने हों या मॉड्यूलर प्लगिन सिस्टम डिज़ाइन करने हों, कंट्रोल किए गए फ़्रेम की मदद से, स्ट्रक्चर्ड, अनुमति वाले, और सुरक्षित एनवायरमेंट में बेहतर कंट्रोल मिलता है. इसलिए, ये अगली जनरेशन के अडवांस वेब ऐप्लिकेशन के लिए एक ज़रूरी टूल हैं.

कुछ और संसाधन