Перед тем, как кто-то пометит этот пост как дубликат другого поста, например: SecurityError: заблокировал фрейм с происхождением от доступа к фрейму перекрестного происхождения этот пост отличается тем, что пытается избежать этой ошибки в контексте веб-расширения Chrome, что означает, что могут быть уникальные решения.
Я портирую расширение Firefox Quantum на Chrome. Расширение внедряет iFrame в текущую веб-страницу пользователя. Прямо сейчас расширение работает без проблем в Firefox Quantum, вы можете найти его здесь: https://addons.mozilla.org/en-US/firefox/addon/tl-dr-auto-summarizer/?src=search
Источником iFrame является файл HTML с именем «inject.html», который входит в расширение.
Вот сокращенный (чтобы избежать чрезмерной длины поста) код, который внедряет iFrame. Этот код находится в скрипте содержимого на текущей вкладке пользователя:
var iFrame = document.createElement("iFrame");
iFrame.id = "contentFrame";
iFrame.classList.add("cleanslate");
iFrame.style.cssText = "width: 100% !important; height: 100% !important; border: none !important;";
iFrame.src = browser.extension.getURL("inject-content/inject.html");
document.body.appendChild(iFrame);
Вот манифест.json
{
"manifest_version": 2,
"name": "TL;DR - Summarizer",
"version": "3.0",
"description": "Summarizes webpages",
"permissions": [
"activeTab",
"tabs",
"*://*.smmry.com/*"
],
"icons":
{
"48": "icons/border-48.png"
},
"browser_action":
{
"browser_style": true,
"default_popup": "popup/choose_length_page.html",
"default_icon":
{
"16": "icons/summarizer-icon-16.png",
"32": "icons/summarizer-icon-32.png"
}
},
"web_accessible_resources": [
"inject-content/inject.html",
"inject-content/cleanslate.css"
],
"content_security_policy": "script-src 'self' 'sha256-AeZmmPP/9ueCrodQPplotiV3Pw0YW4QqifjUL7NE248='; object-src 'self'"
}
После введения iFrame я установил прослушиватели «щелчка» для кнопок внутри iFrame после загрузки iFrame. Я делаю это, используя следующий пример кода. Однако, хотя следующий код работает в Firefox Quantum, он вызывает исключение в Chrome.
iFrame.onload = () => {
//The error occurs on the following line.
var closeButton = iFrame.contentWindow.document.getElementById("close-btn");
closeButton.addEventListener("click", () => {
//Do Stuff
});
var copyButton = iFrame.contentWindow.document.getElementById("copy-btn");
copyButton.addEventListener("click", () => {
//Do stuff
});
}
Я получаю следующее исключение:
Uncaught DOMException: заблокирован фрейм с источником "http://example.com" от доступа к фрейму перекрестного происхождения.
в HTMLIFrameElement.iFrame.onload (файл: /// C: /Users/vroy1/Documents/Programming/web-extension-summarizer/src/inject-content/inject.js: 58: 56)
Как мне избежать этой ошибки?
Если кому-то интересно, причина, по которой я могу использовать API Promise
и пространство имен browser
внутри расширения Chrome, заключается в том, что я использую полифилл, предоставленный Mozilla, который позволяет мне использовать обещания и browser
пространство имен.
Вот код для всплывающего окна, которое расширение отображает при нажатии на значок на панели инструментов:
//Enable the polyfill for the content script and execute it in the current tab
browser.tabs.executeScript({ file: "/polyfills/browser-polyfill.js" }).then(loadContentScript).catch((error) => logError(error));
function loadContentScript() {
browser.tabs.executeScript({ file: "/inject-content/inject.js" }).then(listenForClicks).catch((error) => logError(error));
}
function listenForClicks() {
document.addEventListener('click', e => {
if (!e.target.classList.contains('btn')) {
return;
} else {
browser.tabs.query({ active: true, currentWindow: true })
.then(tabs => {
browser.tabs.sendMessage(tabs[0].id, { summaryLength: e.target.id, targetURL: tabs[0].url });
});
}
});
}
function logError(error) {
console.log(error);
}
Наконец, вот полный код скрипта контента:
https://pastebin.com/Yrs68zAB