Как отправить массив из сценария содержимого во всплывающий сценарий

Я пытаюсь отправить массив всех ссылок на странице в расширение Chrome. Я получаю данные массива с помощью сценария содержимого и использую сообщения для отправки данных в расширение, к сожалению, при получении сообщения от сценария содержимого массив имеет неполные данные.

Я использую функцию sendMessage для ввода моего сценария содержимого, затем этот сценарий собирает информацию о странице (URL-адрес страницы и ссылки на странице), а затем отправляет ее через сообщение.

Затем это сообщение получает слушатель в popup.js, а затем информация сохраняется в объекте, но, к сожалению, информация неполная.

//Manifest.json
{
    "name": "PHD SEO Tools Test",
    "version": "1.0",
    "description": "SEO Tools Browser Extension First Draft",
    "permissions": [
        "tabs", 
        "activeTab",
        "storage"
    ],
    "background": {
        "scripts": ["background.js"],
        "persistent": false
    },
    "browser_action": {
        "default_popup": "popup.html"
    },
      "options_page": "options.html",
    "manifest_version": 2
}
//ContentScript.js
//Store page information in an object
let pageInfo = {
    currentPageURL: window.location.href,
    links: []
}

//Grab all links on the page
links = document.getElementsByTagName("link");
//Grab URL for each link
for (i = 0; i < links.length; i++) {
    //Push url to pageInfo object
    pageInfo.links.push(links[i]);
}

//Send a message containing the pageInfo properties 
chrome.runtime.sendMessage({
    //To add data to the message payload add another property below
    url: pageInfo.currentPageURL, 
    links: pageInfo.links
}, response => {
    console.log(response);
})
//Popup.js
//Variable to store recieved messages
let pageInfo = {
    currentPageURL: '',
    links: []
}

//Variable to store popup UI components
let ui = {
    popup: document.getElementById("main"),
    displayUrlButton: document.getElementById("displayUrlButton"),
    displayUrl: document.getElementById("displayUrl")
}

//Recieve message from background using the following notation:
//request.url
//request.links
chrome.runtime.onMessage.addListener(
    (request, sender, sendResponse) => {
        console.log(request)
        pageInfo.currentPageURL = request.url;
        pageInfo.links = request.links;
        sendResponse({message: "info recieved by popup"});
    }
);

ui.displayUrlButton.addEventListener('click', () => {
    //If ui.displayUrl is empty
    if(ui.displayUrl.childNodes.length < 2) {
        //create a h2 element
        let urlText = document.createElement("h2");
        //set the content of the h2 element
        urlText.innerHTML = "Current page: " + pageInfo.currentPageURL;
        //Add h2 element to page
        ui.displayUrl.appendChild(urlText);
    }
})

function sendMessage() {
//Query tabs for the active tab in the current window
chrome.tabs.query({active: true, currentWindow: true}, tabs => {
    //Execute a script on the active tab
    chrome.tabs.executeScript(tabs[0].id, {file: 'contentScript.js'});
  });
}

После вызова функции sendMessage() я ожидал бы увидеть объект с URL-адресом страницы и массив, полный ссылок (весь элемент html в форме объекта, а не только href). Однако вывод, который я получаю, таков:

{url: "https://www.freecodecamp.org/news/", links: Array(8)}
links: Array(8)
0:
__proto__: Object
1: {}
2: {}
3: {}
4: {}
5: {}
6: {}
7: {}
length: 8
__proto__: Array(0)
url: "https://www.freecodecamp.org/news/"
__proto__: Object

Как вы можете видеть, URL-адрес передается из contentScript, а массив передается из contentScript во всплывающее окно, однако, к сожалению, массив полон пустых элементов.

Как я могу получить массив ссылок, чтобы показать фактическое содержимое следующим образом:

(8) [link, link, link, link, link, link, link, link]
0: link
...
baseURI: "https://www.freecodecamp.org/news/"
href: "https://cdn.freecodecamp.org/news-assets/prism-1-16-
outerHTML: "<link rel="stylesheet" type="text/css" href="https://cdn.freecodecamp.org/news-assets/prism-1-16-
__proto__: HTMLLinkElement
...
1: link
2: link
3: link
4: link
5: link
6: link
7: link
length: 8
__proto__: Array(0)

person Rajeev Gill    schedule 10.06.2019    source источник
comment
Вы не можете отправлять элементы DOM. Поддерживаются только простые типы, такие как строки/числа и массивы или объекты таких типов. Вы можете просто отправить строку URL. Также обратите внимание, что всплывающее окно запускается только при отображении, поэтому вам может потребоваться переключить направление обмена сообщениями — всплывающее окно отправит сообщение через chrome.tabs.sendMessage в сценарий содержимого, который ответит в своем onMessage.   -  person wOxxOm    schedule 11.06.2019


Ответы (2)


Да, вы не можете передать массив из всплывающего окна в контент или наоборот. Обойти это можно просто создать оператор foreach для вашего массива и передавать его по одному за раз.

Всплывающее окно.js:

 ary.forEach(element => {
      chrome.tabs.sendMessage(tabs[0].id, element);
 });

В вашем скрипте, который вы хотите получить, вы просто перестраиваете его.

Content.js

 if(request != 'import' || request != 'scan'){
        arr.push(request);
 }

В приведенном выше случае я создавал только две команды. Эти две команды были отправлены через chrome.tabs.sendMessage(tab[0], <arg>);

Пока вы указываете, что если отправляемый аргумент не имеет никакого значения, кроме добавления в массив, вы успешно перестроите свой массив. Пример того, о чем я говорю, приведен выше в content.js.

person Bibikski    schedule 30.07.2020

Вы не можете отправлять элементы DOM. Поддерживаются только простые типы, такие как строки/числа и массивы или объекты таких типов. Вы можете просто отправить строку URL. Также обратите внимание, что всплывающее окно запускается только при отображении, поэтому вам может потребоваться переключить направление обмена сообщениями — всплывающее окно отправит сообщение через chrome.tabs.sendMessage в сценарий содержимого, который ответит в своем onMessage.

Предоставлено — wOxxOm

person Rajeev Gill    schedule 11.06.2019