customElements.define('x-frame-bypass', class extends HTMLIFrameElement { static get observedAttributes() { return ['src'] } constructor () { super() } attributeChangedCallback () { this.load(this.src) } connectedCallback () { this.sandbox = '' + this.sandbox || 'allow-forms allow-modals allow-pointer-lock allow-popups allow-popups-to-escape-sandbox allow-presentation allow-same-origin allow-scripts allow-top-navigation-by-user-activation' // all except allow-top-navigation } load (url, options) { if (!url || !url.startsWith('http')) throw new Error(`X-Frame-Bypass src ${url} does not start with http(s)://`) console.log('X-Frame-Bypass loading:', url) this.srcdoc = `
` this.fetchProxy(url, options, 0).then(res => res.text()).then(data => { if (data) this.srcdoc = data.replace(/]*)>/i, ` `) }).catch(e => console.error('Cannot load X-Frame-Bypass:', e)) } fetchProxy (url, options, i) { const proxies = (options || {}).proxies || [ window.BASE_URL + 'cors-anywhere?url=', 'https://cors-anywhere.herokuapp.com/', 'https://yacdn.org/proxy/', 'https://api.codetabs.com/v1/proxy/?quest=' ] return fetch(proxies[i] + url, options).then(res => { if (!res.ok) throw new Error(`${res.status} ${res.statusText}`); return res }).catch(error => { if (i === proxies.length - 1) throw error return this.fetchProxy(url, options, i + 1) }) } }, {extends: 'iframe'})