json 未检查运行时,lastError:无法建立连接,接收端不存在,用我自己的Chrome扩展

yftpprvb  于 2022-12-15  发布在  其他
关注(0)|答案(3)|浏览(214)

我是扩展创建的新手,遇到了一个问题,我已经找到了各种方法来解决这个问题,但是这些方法都与我的方法不同,并且/或者使用清单V2而不是我需要的V3来解决这个问题。
此外,一些修复程序在他们的一端找到了工作,但在我的一端没有,所以我真的不明白这个问题。
我的问题是:

  • 我想做一个chrome扩展来截图我的浏览器和应用程序
  • 我找到了一个在线教程,对我来说似乎是正确的(顺便说一句,唯一使用和截图和V3清单的教程,太完美了!)
  • 按照教程,我得到了以下错误:* 未检查运行时。lastError:无法建立连接。接收端不存在 *。
  • 我寻找了各种方法,但没有任何效果,我最终下载了教程的git代码,但它没有改变任何东西,错误仍然存在
  • 据我所知,错误在下面这行:
chrome.action.onClicked.addListener(function (tab) {
  chrome.desktopCapture.chooseDesktopMedia(
    ["screen", "window", "tab"],
    tab,
    (streamId) => {
      if (streamId && streamId.length) {
        setTimeout(() => {
          chrome.tabs.sendMessage(
            tab.id,
            { name: "stream", streamId },
            (response) => console.log("received user data", response) // error is here, response is undefined
          );
        }, 200);
      }
    }
  );
});

我得到的是undefined而不是响应,我认为这是一个问题,因为它永远不会继续,因此永远不会激活onMessage函数,也不会激活content_script
下面是完整的background.js代码:

chrome.action.onClicked.addListener(function (tab) {
  chrome.desktopCapture.chooseDesktopMedia(
    ["screen", "window", "tab"],
    tab,
    (streamId) => {
      if (streamId && streamId.length) {
        setTimeout(() => {
          chrome.tabs.sendMessage(
            tab.id,
            { name: "stream", streamId },
            (response) => console.log("received user data", response)
          );
        }, 200);
      }
    }
  );
});

chrome.runtime.onMessage.addListener((message, sender, senderResponse) => {
  if (message.name === "download" && message.url) {
    chrome.downloads.download(
      {
        filename: "screenshot.png",
        url: message.url,
      },
      (downloadId) => {
        senderResponse({ success: true });
      }
    );

    return true;
  }
});
  • 内容_脚本 *
chrome.runtime.onMessage.addListener((message, sender, senderResponse) => {
    if (message.name === 'stream' && message.streamId) {
        let track, canvas
        navigator.mediaDevices.getUserMedia({
            video: {
                mandatory: {
                    chromeMediaSource: 'desktop',
                    chromeMediaSourceId: message.streamId
                },
            }
        }).then((stream) => {
            track = stream.getVideoTracks()[0]
            const imageCapture = new ImageCapture(track)
            return imageCapture.grabFrame()
        }).then((bitmap) => {
            track.stop()
            canvas = document.createElement('canvas');
            canvas.width = bitmap.width; //if not set, the width will default to 200px
            canvas.height = bitmap.height;//if not set, the height will default to 200px
            let context = canvas.getContext('2d');
            context.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height)
            return canvas.toDataURL();
        }).then((url) => {
            chrome.runtime.sendMessage({name: 'download', url}, (response) => {
                if (response.success) {
                    alert("Screenshot saved");
                } else {
                    alert("Could not save screenshot")
                }
                canvas.remove()
                senderResponse({success: true})
            })
        }).catch((err) => {
            alert("Could not take screenshot")
            senderResponse({success: false, message: err})
        })
        return true;
    }
})
  • 清单v3*
{
  "name": "Screenshots",
  "version": "0.0.1",
  "description": "Take screenshots",
  "manifest_version": 3,
  "background": {
    "service_worker": "background.js"
  },
  "permissions": ["desktopCapture", "downloads", "tabs", "nativeMessaging"],
  "action": {
    "default_title": "Take a Screenshot"
  },
  "icons": {
    "16": "/assets/icon-16.png",
    "32": "/assets/icon-32.png",
    "48": "/assets/icon-48.png",
    "128": "/assets/icon-128.png"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content_script.js"]
    }
  ]
}

我做了各种研究后尝试了几种方法

  • 禁用我的扩展(这毫无意义,但你永远不会知道)
  • 为响应添加一个超时,我尝试了最多20秒的延迟,但没有成功
  • 在各处添加断点以查看它是否与线交叉
vojdkbi0

vojdkbi01#

下面是一个没有service worker和内容脚本的实现。
manifest.json

{
  "name": "desktopCapture",
  "version": "1.0",
  "manifest_version": 3,
  "permissions": [
    "desktopCapture",
    "tabs",
    "downloads"
  ],
  "action": {
    "default_popup": "popup.html"
  }
}

popup.html

<html>
<body>
  <script src="popup.js"></script>
</body>
</html>

popup.js

const createDate = {
  url: "desktopCaptuer.html",
  type: "popup",
  width: 800,
  height: 600
};
chrome.windows.create(createDate);

desktopCaptuer.html

<html>
<body>
  <input type="button" id="captuer" value="Captuer">
  <script src="desktopCaptuer.js"></script>
</body>
</html>

desktopCaptuer.js

chrome.windows.getCurrent({}, w => {
  chrome.windows.update(w.id, { focused: true }, () => {
    document.getElementById("captuer").onclick = () => {
      const sources = ["screen", "window", "tab"];
      chrome.tabs.getCurrent((tab) => {
        chrome.desktopCapture.chooseDesktopMedia(sources, tab, (streamId) => {
          let track, canvas;
          navigator.mediaDevices.getUserMedia({
            video: {
              mandatory: {
                chromeMediaSource: "desktop",
                chromeMediaSourceId: streamId
              },
            }
          }).then((stream) => {
            track = stream.getVideoTracks()[0];
            const imageCapture = new ImageCapture(track);
            return imageCapture.grabFrame();
          }).then((bitmap) => {
            track.stop();
            canvas = document.createElement("canvas");
            canvas.width = bitmap.width;
            canvas.height = bitmap.height;
            let context = canvas.getContext("2d");
            context.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height);
            return canvas.toDataURL();
          }).then((url) => {
            chrome.downloads.download({
              filename: "screenshot.png",
              url: url,
            }, () => {
              canvas.remove();
            });
          }).catch((err) => {
            console.log(err);
            alert("Could not take screenshot");
          })
        });
      });
    }
  });
});
ki1q1bka

ki1q1bka2#

适用于我,使用 chrome 107.0.5304.121(官方.构建)Arch Linux(64位)。
1.转到https://stackoverflow.com/
1.单击扩展图标。
1.此时将打开一个新窗口,其中显示文本“选择要共享的内容。屏幕截图希望与www.example.com共享您的屏幕内容stackoverflow.com“
1.单击其中一个选项卡:整个屏幕、窗口、Chromium选项卡
1.单击屏幕截图预览或选项卡标题
1.点击“分享”
1.浏览器会显示一条带有文本“Screenshot saved”(屏幕快照已保存)的警报,并在默认下载目录中创建一个名为“Screenshot.png”的文件。

ldfqzlk8

ldfqzlk83#

所以,@Norio Yamamoto的解决方案非常适合我,因为我需要在屏幕上给予一个名字,并进行其他处理,所以感谢您的帮助,我已经开始理解扩展上的HTML弹出窗口了!谢谢!
对于问题本身,我最终通过重新安装chrome“修复”了它,它就像@托马斯Muller告诉我的那样工作...不知道为什么,也许我不得不在多次测试中破坏一些东西,所以应用程序已经工作了
但我注意到一个问题的教程版本相比,一个弹出窗口,教程版本不工作:非重载页面(顺便感谢@wOxxOm的提示),也不是chrome主页,也不是扩展页面,所以我真的更喜欢弹出版本,但我需要挖掘更多来改进
再次感谢!

相关问题