返回首頁 

讨论»开发

Access Iframe Content

发表于:2019-04-06

Access Iframe Content

I'm trying to access a video inside an iframe, but I am getting the error "Permission denied to access property x on cross-origin object" for the innerDoc video. The iframe is youtube, so I have this as my userscript property:

// @include https://original-website.com/*// @match *.youtube.com/*

And here is my javascript:

    var video, mode, iframe, innerDoc;$('.speed-control button').on('click', (evt) => {mode = $(event.target).attr('class').match(/speed-control-(.*)/)[1];iframe = document.getElementById('videoPlayer_Youtube_api');innerDoc = (iframe.contentWindow || iframe.contentDocument);video = innerDoc.querySelectorAll('video');switch(mode){case 'slow':video.playbackRate  = 0.5;break;case 'normal':video.playbackRate  = 1;break;case 'fast':video.playbackRate  = 2;break;default:}});
woxxom管理员
发表于:2019-04-06

Modern browsers can't access a cross-domain iframe contents directly. Since your userscript runs both on the main page and inside the iframe you can use cross-window messaging:

const MSG_PREFIX = GM_info.script.name + '\n';if (window === top) {$('.speed-control button').on('click', function () {const payload = JSON.stringify({action: 'speedControl',data: this.className.match(/speed-control-(.*)/)[1],});const iframe = document.getElementById('videoPlayer_Youtube_api');iframe.contentWindow.postMessage(MSG_PREFIX + payload, '*');});} else if (location.hostname.endsWith('youtube.com')) {const ACTIONS = {speedControl(mode) {switch (mode) {case 'slow':video.playbackRate = 0.5;break;case 'normal':video.playbackRate = 1;break;case 'fast':video.playbackRate = 2;break;default:}},};window.addEventListener('message', e => {if (typeof e.data === 'string' && e.data.startsWith(MSG_PREFIX)) {try {const payload = e.data.slice(MSG_PREFIX.length);const {action, data} = JSON.parse(payload);if (ACTIONS.hasOwnProperty(action)) {ACTIONS[action](data);}}catch (ex) {}}});}
发表于:2019-04-06

Thank you so much! I just had to define the video variable but other than that, your code works really well. Gonna look into postMessage more to understand it better.

发表回复

登录以发表回复。