Расширение Chrome - Uncaught DOMException: заблокирован фрейм с источником от доступа к фрейму кросс-происхождения - PullRequest
0 голосов
/ 03 мая 2018

Перед тем, как кто-то пометит этот пост как дубликат другого поста, например: 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

Ответы [ 2 ]

0 голосов
/ 04 февраля 2019

Для Chrome - я включил тег script в свой iframe. Затем я мог бы использовать <button element>.addEventListener("click", function() {} внутри скрипта, загруженного в iframe. Для связи между кадрами я использовал window.parent.postMessage и другие подобные методы. Чтобы загрузить iframe, я добавил следующее к своему manifest.json:

  "web_accessible_resources": [
    "inject-content/inject.html",
    "inject-content/cleanslate.css"
  ]
0 голосов
/ 04 февраля 2019

Вы можете попробовать загрузить этот код, то, что вы хотите в своем iframe, на веб-сервер и установить заголовок.

'Access-Control-Allow-Origin: *'

Firefox обычно лучше работает с локальными файлами, которые могут объяснить вашу ошибку

origin "http://example.com" from accessing a cross-origin frame. at file:///C:/Users/vroy1/Documents/Programming/web-extension-summarizer/src/inject-content/inject.js
...