首页 > 解决方案 > 在网页上的所有 iframe 中注入 iframe 的内容脚本

问题描述

我正在尝试创建一个 iframe 并在加载网页时将其注入网页,但是当我尝试这样做时,内容脚本将 iframe 注入网页上的所有 iframe 中,我使用chrome.runtime.onMessage.addListener了当用户单击扩展图标时切换 iframe,因此我从后台脚本发送消息来处理此问题,但是我只从后台脚本发送消息一次,但chrome.runtime.onMessage.addListener被多次触发我不知道为什么

这就是正在发生的事情

这是内容脚本

var iframeContainer = undefined;
window.onload = function () {
  injectPopup();

  chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
    if (request.message == "togglePopup") {
      console.log("message arrived");
      var appBody = document.getElementById("app-container");
      if (appBody.style.display == "none") {
        console.log("posting message");
        iframeContainer.contentWindow.postMessage(
          JSON.stringify({
            user: request.user,
            token: request.token,
          }),
          "*",
          []
        );
        appBody.style.display = "block";
      } else {
        appBody.style.display = "none";
      }
    }
  });
};

// window.addEventListener("message", function (e) {
//   if (JSON.parse(e.data)) {
//     const data = JSON.parse(e.data);

//     if (data.message) {
//       if (data.message == "toggleApp") {
//         var appBody = document.getElementById("app-container");
//         appBody.style.display = "none";
//       }
//     }
//   }
// });

function injectPopup() {
  console.log("inject popup");
  iframeContainer = document.createElement("iframe");
  console.log(iframeContainer);
  iframeContainer.allowFullscreen = false;
  iframeContainer.src = chrome.runtime.getURL("/index.html");
  iframeContainer.id = "app-container-iframe";
  const appContainer = document.createElement("div");
  appContainer.id = "app-container";
  appContainer.style.display = "none";
  console.log(appContainer);
  const resizeHandle = document.createElement("div");
  resizeHandle.id = "resize-container-handle";
  resizeHandle.classList.add("ui-resizable-handle");
  resizeHandle.classList.add("ui-resizable-w");

  resizeHandle.innerHTML =
    '<div class="resize-handle-horizontal-bar"></div><div class="resize-handle-horizontal-bar"></div><div class="resize-handle-horizontal-bar"></div>';

  appContainer.appendChild(resizeHandle);
  document.querySelector("body").appendChild(appContainer);
  appContainer.appendChild(iframeContainer);
  $("#app-container").resizable({
    handles: { w: "#resize-container-handle" },
  });
}

这是我从中发送消息的后台脚本

var userLoggedIn = {};
const openTabs = [];
const apiUrl = "http://localhost:5000";
var popupOpen = false;
var currentWindow = undefined;

window.onload = () => {
  popupOpen = false;
};

chrome.storage.local.get("token", function (result) {
  userLoggedIn = result.token;

  chrome.browserAction.onClicked.addListener(function (tab) {
    const width = 500;
    const height = 900;
    const left = screen.width / 2 - width / 2;
    const top = screen.height / 2 - height / 2;
    console.log("clicked!");
    if (!userLoggedIn) {
      if (currentWindow == undefined) {
        chrome.windows.create(
          {
            url: "/html/auth.html",
            width: width,
            height: height,
            left: left,
            top: top,
            focused: true,
          },
          (window) => {
            currentWindow = window;
            chrome.windows.onRemoved.addListener(function (id) {
              if (currentWindow.id == id) {
                currentWindow = undefined;
              }
            });
          }
        );
      }
    } else {
      console.log("hi!");
      chrome.windows.getCurrent((w) => {
        chrome.tabs.query(
          {
            active: true,
            currentWindow: true,
          },
          function (tabs) {
            const userData = parseJwt(userLoggedIn);
            console.log("sending message");
            chrome.tabs.sendMessage(tabs[0].id, {
              message: "togglePopup",
              user: userData,
              token: userLoggedIn,
            });
          }
        );
      });
    }
  });

  chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
    if (request.message === "login") {
      loginUser(request.payload)
        .then(function (res) {
          if (res.ok) {
            return res.json();
          } else {
            sendResponse({
              message: "error",
            });
          }
        })
        .then(function (data) {
          chrome.storage.local.set({ token: data.token }, function (result) {
            chrome.windows.remove(currentWindow.id);
            const userData = parseJwt(data.token);
            userLoggedIn = data.token;
            chrome.tabs.query(
              {
                active: true,
                currentWindow: true,
              },
              function (tabs) {
                chrome.tabs.sendMessage(tabs[0].id, {
                  message: "togglePopup",
                  payload: {
                    user: userData,
                    token: userLoggedIn,
                  },
                });
              }
            );

            sendResponse({ message: "success" });
          });
        })
        .catch(function (err) {
          console.log(err);
        });
      return true;
    } else if (request.message === "register") {
      registerUser(request.payload)
        .then(function (res) {
          if (res.ok) {
            return res.json();
          } else {
            sendResponse({
              message: "error",
            });
          }
        })
        .then(function (data) {
          console.log(data);
          sendResponse({ message: "success" });
        })
        .catch(function (err) {
          console.log(err);
        });
    } else if (request.message === "logout") {
    } else if (request.message === "userStatus") {
    } else if (request.message === "closePopup") {
      const index = getIndexOfTab(sender.tab.id, openTabs);
      openTabs[index].popupOpen = false;
    }
  });
});

标签: javascripthtmljqueryiframegoogle-chrome-extension

解决方案


chrome.tabs.sendMessage根据文档将消息发送到选项卡的所有框架。

您可以通过以下方式将其限制在主页上frameId

chrome.tabs.sendMessage(tabId, {foo: 'bar'}, {frameId: 0});

推荐阅读