如果您希望页面完全不可见,我认为唯一的选择是将其加载到背景页面上的 iframe 中。然后,您可以使用内容脚本访问 iframe 中的页面,就像访问任何正常的可见页面一样。
由于许多网站限制使用 X-Frame-Options 标头进行嵌入,因此您可能必须使用 webRequest API 删除该标头,然后才能将页面加载到 iframe 中。一些页面还使用其他技术来防止嵌入,这可能会使这进一步复杂化。
示例代码:
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);
几点说明:
-
X-Frame-Options header 的去除不限于这里的背景页面。它也允许将相关页面嵌入到任何其他页面的 iframe 中。不幸的是,Chrome 似乎不支持 ALLOW-FROM uri 值,该值可用于限制仅嵌入到您的扩展程序中。
- 内容脚本被注入到这里的所有页面。您可以仅以编程方式将其注入到背景页面上的 iframe,但这会变得有点复杂。
- 我以
www.google.fr 为例,因为它使用X-Frame-Options,但没有使用任何其他技术来防止嵌入。我使用法语域是因为google.com 倾向于自动重定向到本地国家级域。