Skip to content

Instantly share code, notes, and snippets.

@uangsl
Last active November 9, 2023 01:34
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save uangsl/63978e459df3037cc8ec0d808d8b7df3 to your computer and use it in GitHub Desktop.
Save uangsl/63978e459df3037cc8ec0d808d8b7df3 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