Last active
November 9, 2023 01:34
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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