Skip to content

Instantly share code, notes, and snippets.

@santaklouse
Forked from uangsl/iframe-loader.js
Created September 8, 2025 16:50
Show Gist options
  • Save santaklouse/7535801a39887fa69c4fdae82c86418c to your computer and use it in GitHub Desktop.
Save santaklouse/7535801a39887fa69c4fdae82c86418c to your computer and use it in GitHub Desktop.
load webpage by XMLHttpRequest, and insert HTML into iframe by DOMParser. then the main page can visit iframe's context without cross-domain problem
const IFRAME_READY_MESSAGE = "IFRAME_READY";
export default {
id: null,
$el: null,
iframeBaseUrl: null,
targetDocument: document,
style:{'position':'fixed', 'top': '0', 'right':'20px', 'width':'300px', 'height':'400px'},
/***
* {id: '', url: '', iframeBaseUrl:'' , style:{}, targetDocument: null}
*/
load(args){
const th = this;
th.id = args.id;
th.iframeBaseUrl = args.iframeBaseUrl;
if(args.targetDocument)
th.targetDocument = args.targetDocument;
if(!args.style)
args.style = th.style;
return new Promise(function(resolve, reject){
th.$el = document.createElement('iframe');
var _onReady = function(event) {
if(IFRAME_READY_MESSAGE == event.data.type){
window.removeEventListener("message", _onMessage);
resolve(th.$el);
}
};
window.addEventListener("message", _onReady);
th.$el.setAttribute("id", th.id);
th._setIFrameStyle(args.style);
th.$el.onload = function(){
var iframedoc = th.$el.contentWindow.document;
var onResponse = function() {
th._loadHTML(this.responseText);
}
var oReq = new XMLHttpRequest(),blob;
oReq.responseType = "text";
oReq.addEventListener("load", onResponse);
oReq.open("get", args.url, true);
oReq.send();
}
th.targetDocument.documentElement.appendChild(th.$el);
});
},
ready(){
window.parent.postMessage({type:IFRAME_READY_MESSAGE},'*');
},
_loadHTML(html){
const th = this;
var iframedoc = th.$el.contentWindow.document;
var parser = new DOMParser();
var doc = parser.parseFromString(html, "text/html");
var scripts = [];
//remove <script> from doc
doc.documentElement.querySelectorAll('script').forEach((item)=>{
item.parentElement.removeChild(item);
scripts.push(item);
});
iframedoc.head.innerHTML = "<base href='" + th.iframeBaseUrl + "' />" + doc.querySelector('head').innerHTML;
iframedoc.body.innerHTML = doc.querySelector('body').innerHTML;
//add <script> to iframe
scripts.forEach((item)=>{
var s = iframedoc.createElement( 'script' );
s.type = item.getAttribute("type");
s.src = item.getAttribute("src");
iframedoc.body.appendChild(s);
});
},
_setIFrameStyle(style){
const th = this;
th.$el.setAttribute("style", "overflow:hidden;background-color:#fff;z-index:2147483637;border:none;box-shadow:0 1px 10px #555;");
if(style.position)
th.$el.style.position = style.position;
if(style.top)
th.$el.style.top = style.top;
if(style.right)
th.$el.style.right = style.right;
if(style.bottom)
th.$el.style.bottom = style.bottom;
if(style.left)
th.$el.style.left = style.left;
if(style.width)
th.$el.style.width = style.width;
if(style.height)
th.$el.style.height = style.height;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment