I am trying to load a website inside an iFrame but the server is sending the X-Frame-Options: SAMEORIGIN
header so I've tried to use onHeadersReceived to modify the headers though I cannot get it to work.
manifest.json
{
"manifest_version": 2,
"name": "__MSG_extensionName__",
"description": "__MSG_extensionDescription__",
"default_locale": "en",
"version": "0.1",
"author": "author",
"homepage_url": "https://github.com/",
"icons": {
"48": "assets/icons/logo.png"
},
"background": {
"page": "../../background.html"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["scripts/dist/bundle.js"],
"css": ["assets/css/main.css"]
}
],
"permissions": [
"tabs",
"webRequest",
"contextMenus",
"webNavigation",
"webRequestBlocking"
],
"web_accessible_resources": [
"assets/icons/logo.png"
]
}
background.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script type="module" src="scripts/dist/contextMenu.js"></script>
<script type="module" src="scripts/dist/modifyHeaders.js"></script>
</head>
</html>
contextMenu.js
browser.contextMenus.create( {
id: "customsearch",
title: "Search",
contexts: ["selection"]
} );
// Context menu onClicked listener
browser.contextMenus.onClicked.addListener( (info, tab) => {
if (info.menuItemId = "custom-search") {
sendMessageToTab(tab, info);
}
} );
function sendMessageToTab(tab, info) {
browser.tabs.sendMessage(
tab.id,
{ query: info.selectionText }
);
}
background.js
var extraInfoSpec = ['blocking', 'responseHeaders'];
var filter = {
urls: ['<all_urls>'],
tabId: -1
};
// Bypass X-Frame-Options
browser.webRequest.onHeadersReceived.addListener(
modifyHeadersCallback,
filter,
extraInfoSpec
);
// onHeadersReceived Callback
function modifyHeadersCallback(details) {
let modifiedResponseHeaders = details.responseHeaders.filter(
header => !(header.name.toLowerCase() == 'x-frame-options' || header.name.toLowerCase() == 'content-security-policy')
);
return {responseHeaders: modifiedResponseHeaders};
};
Context menu works as expected, the problem is with the browser.webRequest.onHeadersReceived
listener which seems to not get fired at all as I don't get any errors or logs to the console.
I did any extensive search and tried most of the solutions I've found but nothing worked for my case. Can you spot anything wrong in my approach?
All you need is to remove tabId: -1
from your filter
object:
browser.webRequest.onHeadersReceived.addListener(
modifyHeadersCallback,
{ urls: ['<all_urls>'] },
['blocking', 'responseHeaders']
);
Modern Chrome requires the extraHeaders
mode in extraInfoSpec parameter so the universal code for iframes would look like this:
browser.webRequest.onHeadersReceived.addListener(
modifyHeadersCallback,
{ urls: ['<all_urls>'], types: ['sub_frame'] },
// Modern Chrome needs 'extraHeaders' to see and change this header,
// so the following code evaluates to 'extraHeaders' only in modern Chrome.
['blocking', 'responseHeaders', chrome.webRequest.OnHeadersReceivedOptions.EXTRA_HEADERS]
.filter(Boolean)
);
And of course "permissions"
in manifest.json should contain the URLs you want to process e.g. in this case it's "<all_urls>"
.
So, this is either a bug or an intentional change, which wasn't documented yet, so if someone wants to report it please open a new issue on https://crbug.com. I guess it's intentional because the extraHeaders
mode means this header is handled in the internal network process, which is separate from the browser process.