জাভাস্ক্রিপ্ট ব্যবহার করে কোনও ভিন্ন উত্সের আইফ্রেমের সাথে আলাপচারিতা সম্ভব নয় যাতে এর আকার পেতে পারে; এটি করার একমাত্র উপায় হ'ল ব্যবহার করাwindow.postMessage
সঙ্গে targetOrigin
আপনার ডোমেনে সেট বা wildchar *
আইফ্রেম উৎস থেকে। আপনি বিভিন্ন উত্সের সাইটগুলি এবং ব্যবহারের সামগ্রীগুলি প্রক্সি করতে পারেন srcdoc
তবে এটি হ্যাক হিসাবে বিবেচিত এবং এটি এসপিএ এবং আরও অনেক গতিশীল পৃষ্ঠাগুলির সাথে কাজ করবে না।
একই উত্স iFrame আকার
ধরা যাক, আমাদের দুটি একই উত্সের আইফ্রেম রয়েছে, একটি ছোট উচ্চতা এবং স্থির প্রস্থ:
<!-- iframe-short.html -->
<head>
<style type="text/css">
html, body { margin: 0 }
body {
width: 300px;
}
</style>
</head>
<body>
<div>This is an iFrame</div>
<span id="val">(val)</span>
</body>
এবং একটি দীর্ঘ উচ্চতা আইফ্রেম:
<!-- iframe-long.html -->
<head>
<style type="text/css">
html, body { margin: 0 }
#expander {
height: 1200px;
}
</style>
</head>
<body>
<div>This is a long height iFrame Start</div>
<span id="val">(val)</span>
<div id="expander"></div>
<div>This is a long height iFrame End</div>
<span id="val">(val)</span>
</body>
আমরা load
ব্যবহার iframe.contentWindow.document
করে প্যারেন্ট উইন্ডোতে প্রেরণ করব তা ব্যবহার করে আমরা ইভেন্টে আইফ্রেম আকার পেতে পারিpostMessage
:
<div>
<iframe id="iframe-local" src="iframe-short.html"></iframe>
</div>
<div>
<iframe id="iframe-long" src="iframe-long.html"></iframe>
</div>
<script>
function iframeLoad() {
window.top.postMessage({
iframeWidth: this.contentWindow.document.body.scrollWidth,
iframeHeight: this.contentWindow.document.body.scrollHeight,
params: {
id: this.getAttribute('id')
}
});
}
window.addEventListener('message', ({
data: {
iframeWidth,
iframeHeight,
params: {
id
} = {}
}
}) => {
// We add 6 pixels because we have "border-width: 3px" for all the iframes
if (iframeWidth) {
document.getElementById(id).style.width = `${iframeWidth + 6}px`;
}
if (iframeHeight) {
document.getElementById(id).style.height = `${iframeHeight + 6}px`;
}
}, false);
document.getElementById('iframe-local').addEventListener('load', iframeLoad);
document.getElementById('iframe-long').addEventListener('load', iframeLoad);
</script>
আমরা উভয় আইফ্রেমে যথাযথ প্রস্থ এবং উচ্চতা পাব; আপনি এটি এখানে অনলাইনে চেক করতে পারেন এবং এখানে স্ক্রিনশটটি দেখতে পারেন ।
বিভিন্ন উত্স আইফ্রেম আকার হ্যাক ( হয়নি )
এখানে বর্ণিত পদ্ধতিটি হ্যাক এবং এটি ব্যবহার করা উচিত যদি এটি একেবারে প্রয়োজনীয় এবং আশেপাশে অন্য কোনও উপায় না থাকে; এটি বেশিরভাগ গতিশীল উত্পন্ন পৃষ্ঠাগুলি এবং এসপিএগুলির জন্য কাজ করবে না । পদ্ধতিটি কর্স নীতিকে বাইপাস করতে একটি প্রক্সি ব্যবহার করে পৃষ্ঠার এইচটিএমএল উত্স কোডটি আনে (cors-anywhere
এটি একটি সাধারণ সিওআরএস প্রক্সি সার্ভার তৈরি করার একটি সহজ উপায় এবং এটিতে একটি অনলাইন ডেমো রয়েছেhttps://cors-anywhere.herokuapp.com
) এটি তখন জেএস কোডটিকে সেই এইচটিএমএলকে ইনজেকশন দেয় postMessage
এবং এর আকারটি প্রেরণ করতে পারে মূল নথিতে আইফ্রেম। এমনকি এটি আইফ্রেমে resize
( আইফ্রেমের সাথে মিলিতwidth: 100%
) ইভেন্ট পরিচালনা করে এবং আইফ্রেম আকারটি পিতামাতার কাছে পোস্ট করে।
patchIframeHtml
:
আইফ্রেম এইচটিএমএল কোডটি প্যাচ করার জন্য একটি ফাংশন এবং কাস্টম জাভাস্ক্রিপ্ট ইনজেক্ট postMessage
করার জন্য যা আইফ্রেম আকারটি পিতামাতার কাছে প্রেরণে ব্যবহার করবেload
এবং এর resize
। যদি origin
প্যারামিটারের জন্য কোনও মান থাকে , তবে এইচটিএমএল <base/>
উপাদানটি সেই উত্সের URL টি ব্যবহার করে মাথায় চাপ দেওয়া হবে, এইভাবে, এইচটিএমএল ইউআরআইগুলি /some/resource/file.ext
আইফ্রেমের অভ্যন্তর মূল URL দ্বারা সঠিকভাবে আনা হবে।
function patchIframeHtml(html, origin, params = {}) {
// Create a DOM parser
const parser = new DOMParser();
// Create a document parsing the HTML as "text/html"
const doc = parser.parseFromString(html, 'text/html');
// Create the script element that will be injected to the iFrame
const script = doc.createElement('script');
// Set the script code
script.textContent = `
window.addEventListener('load', () => {
// Set iFrame document "height: auto" and "overlow-y: auto",
// so to get auto height. We set "overlow-y: auto" for demontration
// and in usage it should be "overlow-y: hidden"
document.body.style.height = 'auto';
document.body.style.overflowY = 'auto';
poseResizeMessage();
});
window.addEventListener('resize', poseResizeMessage);
function poseResizeMessage() {
window.top.postMessage({
// iframeWidth: document.body.scrollWidth,
iframeHeight: document.body.scrollHeight,
// pass the params as encoded URI JSON string
// and decode them back inside iFrame
params: JSON.parse(decodeURIComponent('${encodeURIComponent(JSON.stringify(params))}'))
}, '*');
}
`;
// Append the custom script element to the iFrame body
doc.body.appendChild(script);
// If we have an origin URL,
// create a base tag using that origin
// and prepend it to the head
if (origin) {
const base = doc.createElement('base');
base.setAttribute('href', origin);
doc.head.prepend(base);
}
// Return the document altered HTML that contains the injected script
return doc.documentElement.outerHTML;
}
getIframeHtml
:
যদি একটি প্রক্সি ব্যবহার করে সিওআরএসকে বাইপাস করে কোনও পৃষ্ঠার এইচটিএমএল পাওয়ার জন্য একটি ক্রিয়া useProxy
প্যারাম সেট করা । postMessage
আকারের ডেটা প্রেরণ করার সময় অতিরিক্ত প্যারামিটারগুলি পাস করা হবে ।
function getIframeHtml(url, useProxy = false, params = {}) {
return new Promise(resolve => {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
// If we use a proxy,
// set the origin so it will be placed on a base tag inside iFrame head
let origin = useProxy && (new URL(url)).origin;
const patchedHtml = patchIframeHtml(xhr.responseText, origin, params);
resolve(patchedHtml);
}
}
// Use cors-anywhere proxy if useProxy is set
xhr.open('GET', useProxy ? `https://cors-anywhere.herokuapp.com/${url}` : url, true);
xhr.send();
});
}
বার্তা ইভেন্টের হ্যান্ডলার ফাংশনটি "একই উত্স iFrame আকার" এর মতোই ।
আমরা এখন আমাদের কাস্টম জেএস কোড ইনজেকশন সহ কোনও আইফ্রেমের অভ্যন্তরে ক্রস অরিজিন ডোমেন লোড করতে পারি:
<!-- It's important that the iFrame must have a 100% width
for the resize event to work -->
<iframe id="iframe-cross" style="width: 100%"></iframe>
<script>
window.addEventListener('DOMContentLoaded', async () => {
const crossDomainHtml = await getIframeHtml(
'https://en.wikipedia.org/wiki/HTML', true /* useProxy */, { id: 'iframe-cross' }
);
// We use srcdoc attribute to set the iFrame HTML instead of a src URL
document.getElementById('iframe-cross').setAttribute('srcdoc', crossDomainHtml);
});
</script>
এবং আমরা overflow-y: auto
আইফ্রেম বডি ব্যবহার করে এমনকি কোনও উল্লম্ব স্ক্রোলিং ছাড়াই এর সামগ্রীর পুরো উচ্চতায় আইফ্রেম আকারে পেয়ে যাব ( করতে হবে এটি এমন হওয়া উচিত overflow-y: hidden
যাতে আমরা আকার পরিবর্তনে স্ক্রোলবার ঝাঁকুনি না পাই )।
আপনি এটি অনলাইনে চেক করতে পারেন এখানে ।
আবার খেয়াল করে দেখুন যে এটি একটি হ্যাক এবং এটি এড়ানো উচিত ; আমরা ক্রস-অরিজিন আইফ্রেম নথিটি অ্যাক্সেস করতে পারি না বা কোনও ধরণের জিনিস ইনজেকশন করতে পারি না ।