I've made a Chrome Extension that loads my New Tab page with an <iframe>
of my YouTube subscription page (I got around the X-frame-options
issue) and want to isolate a specific element of the document, #content
to be exact (that being the subscription feed). Whether that be subtracting everything that is :not(#content)
or cutting #content
out and putting it into another <div>
are both viable. Here's my code:
Background.html
<html>
<head>
<script type="text/javascript" src="jquery-2.2.0.min.js"></script>
<script type="text/javascript" src="script.js"></script>
<script type="text/javascript" src="window.js"></script>
</head>
<body>
<iframe id="left" name="left"></iframe>
<div id="canvas"></div>
</body>
</html>
Window.js
$(document).ready(function(){
var $left = $('#left');
$left.on('load', function() {
$(this).contents().find('#content').clone().appendTo('#canvas');
});
$left.attr('src', 'https://www.youtube.com/feed/subscriptions');
});
Script.js
chrome.webRequest.onHeadersReceived.addListener(
function(info) {
var headers = info.responseHeaders;
for (var i = headers.length - 1; i >= 0; --i) {
var header = headers[i].name.toLowerCase();
if (header == 'x-frame-options' || header == 'frame-options') {
headers.splice(i, 1); // Remove header
}
}
return {
responseHeaders: headers
};
}, {
urls: ['*://*/*'], // Pattern to match all http(s) pages
types: ['sub_frame']
}, ['blocking', 'responseHeaders']
);
Manifest.json
{
"manifest_version": 2,
"version": "1.0",
"background": "background.html",
"chrome_url_overrides" : {
"newtab": "background.html"
},
"permissions": [
"background",
"contextMenus",
"webRequest",
"webRequestBlocking",
"tabs",
"<all_urls>"
]
}
As it is right now, YouTube loads, but I can't get a hold of the document in the <iframe>
, as it's logging an error of:
Uncaught SecurityError: Failed to read the 'contentDocument' property from
'HTMLIFrameElement': Blocked a frame with origin "chrome-extension://ID" from
accessing a frame with origin "https://www.youtube.com". The frame requesting
access has a protocol of "chrome-extension", the frame being accessed has a
protocol of "https". Protocols must match.
I'm trying to get that div#content
isolated for ease of navigation from my new tab page. I've seen solutions that propose using "all_frames":true
in the manifest.json
file, but that doesn't seem to solve it. Any ideas? Thanks!
From the description here and chrome extension related questions you asked these days, I'd like to suggest you learn more from Official Guide, since it seems you are confused by Event page and content scripts ( you should know all_frames only apply to content scripts).
Take a look at Same-origin Policy and you should know Chrome extension doesn't allow you to access contentDocument of the iframe.
Since your purpose is to extract the #content part from youtube then append that to your canvas in new tab page, why not
The code looks like:
Manifest.json
newtab.html
script.js
Please be aware that the original image src in youtube page looks like
src="//..."
, you should add the right domain before//
in your chrome extension. And youtube has many scripts to load, you also need to deal with that part of logic.Last by not least, I think the best way is to find some public 3rd party api from youtube, I didn't use it but it seems Youtube | Google Developer may help.