If you want the page to be completely invisible, I believe that the only option is to load it into an iframe on the background page. You can then access the page within the iframe using content scripts, just as you would access any normal visible page.
Since many sites limit embedding using the X-Frame-Options
header, you will likely have to use the webRequest API to remove that header before loading the page into an iframe. Some pages also use other techniques to prevent embedding that might further complicate this.
Example code:
manifest.json
{
"manifest_version": 2,
"name": "Hidden page in background",
"description": "Interact with a hidden page in background",
"version": "1.0",
"background": {
"page": "background.html",
"persistent": true
},
"content_scripts": [
{
"matches": ["*://*.google.fr/*"],
"js": ["contentscript.js"],
"all_frames": true
}
],
"permissions": ["*://*.google.fr/*", "webRequest", "webRequestBlocking"]
}
background.html
<!DOCTYPE html>
<html>
<head>
<script src="background.js"></script>
</head>
<body>
<iframe id="iframe1" width="1000 px" height="600 px" src="http://www.google.fr"></iframe>
</body>
</html>
background.js
// This is to remove X-Frame-Options header, if present
chrome.webRequest.onHeadersReceived.addListener(
function(info) {
var headers = info.responseHeaders;
var index = headers.findIndex(x=>x.name.toLowerCase() == "x-frame-options");
if (index !=-1) {
headers.splice(index, 1);
}
return {responseHeaders: headers};
},
{
urls: ['*://*.google.fr/*'], //
types: ['sub_frame']
},
['blocking', 'responseHeaders']
);
contentscript.js
var elementToInsert = document.createElement("h1");
elementToInsert.textContent = "This text comes from my content script.";
document.body.insertBefore(elementToInsert, document.body.firstChild);
Couple of notes:
- The removal of
X-Frame-Options
header is not limited to the background page here. It would allow embedding of the relevant page in iframes on any other page as well. Unfortunately, Chrome does not seem to support the ALLOW-FROM uri
value that could be used to limit embedding to your extension only.
- Content script is being injected to all pages here. You could inject it programmatically only to the iframe on the background page, but that gets a bit more complicated.
- I used
www.google.fr
as an example, because it uses X-Frame-Options
, but does not use any other techniques to prevent embedding. I used the French domain because google.com
tends to redirect to local country-level domains automatically.