Wie gehe ich mit “Unchecked runtime.lastError: The Message Port closed before a response was Received” um?

Lesezeit: 5 Minuten

Benutzer-Avatar
bongoSLAP

Verzeihen Sie mir alle eklatanten Fehler, da ich neu bei Chrome-Erweiterungen bin, aber dieser Fehler mit der Message-Passing-API von Chrome wurde hier besprochen, hierund hier in der Vergangenheit und die übliche Antwort lautet: „Vorhandene Chrome-Erweiterungen deaktivieren, eine davon verursacht den Fehler“. Ist das das Beste, was erreicht werden kann? Sollen wir einfach umdrehen und die Tatsache akzeptieren, dass unsere Erweiterungen mit anderen in Konflikt geraten? True zurückgeben oder ein Promise für die Listener-Callback-Funktion zurückgeben und verwenden sendResponse löst das Problem bei mir nicht.

Derzeit kann ich nur den neuen Wert speichern chrome.storage.local (keine Fehler) von Deaktivieren Sie alle anderen Chrome-Erweiterungen, entfernen Sie die Erweiterung und laden Sie die entpackte Erweiterung wieder hoch. Der Code scheint interessanterweise nur auf developer.chrome.com zu funktionieren, er funktioniert überhaupt nicht auf den anderen “übereinstimmenden” URLs in manifest.json.

Ich denke, dass es eine gewisse Bedeutung in der gibt await und async Operatoren bei der Lösung dieses Problems, aber ich bin mir nicht sicher, wie ich es richtig implementieren soll.

manifest.json:

{
    "manifest_version": 2,
    "name": "my extension",
    "version": "1.0",
    "description": "its my extension",
    "permissions": [
        "declarativeContent", 
        "storage", 
        "activeTab"
    ],
    "content_scripts": [
        {
          "matches": [
            "*://developer.chrome.com/*",
            "*://bbc.co.uk/*",
            "*://theguardian.com/*",
            "*://dailymail.co.uk/*"
          ],
          "js": ["content.js"]
        }
      ],
    "background": {
      "scripts": ["background.js"],
      "persistent": false
    },
    "content_security_policy": "script-src 'self' https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js; object-src 'self'",
    "page_action": {
        "default_popup": "popup.html"
    },
    "icons": {
        "16": "images/icon16.png",
        "32": "images/icon32.png",
        "48": "images/icon48.png",
        "128": "images/icon128.png"
      }
}

popup.html:

<!DOCTYPE html>
  <html>
    <head>
      <title>my extension</title>
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
      <script src="popup.js"></script>
      <link rel="stylesheet" type="text/css" href="style.css">
    </head>
    <body>
      <h1>my extension</h1>
      <h2>Article: <span id="article-headline"></span></h2>
      <button id="detect-article">Detect Article</button>
    </body>
  </html>

popup.js:

$(document).ready(function() {
    $("#detect-article").click(function() {
        chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
            chrome.tabs.sendMessage(tabs[0].id, {request: "Requesting headline"}, function(response) {
                console.log("Requesting headline")
            });
        });
    });    
})

function getHeadline(changes) {
    let changedValues = Object.keys(changes);
    //console.log(changedValues);

    for (var item of changedValues) {
        console.log("new value: " + changes[item].newValue);
        $("#article-headline").text(changes[item].newValue)
    }
}

chrome.storage.onChanged.addListener(getHeadline);

content.js:

function handleRequest(message, sender, sendResponse) {
    console.log("Request recieved");
    let headlineList = document.getElementsByTagName("h1");
    chrome.storage.local.set({headline: headlineList[0].innerText}, function() {
        console.log("'" + headlineList[0].innerText + "' stored in local storage");
    });
    return true;
}

chrome.runtime.onMessage.addListener(handleRequest);

hintergrund.js:

chrome.runtime.onInstalled.addListener(function() {
    chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
      chrome.declarativeContent.onPageChanged.addRules([{
        conditions: [
          new chrome.declarativeContent.PageStateMatcher({
            pageUrl: { hostContains: 'developer.chrome.com' },
          }),
          new chrome.declarativeContent.PageStateMatcher({
            pageUrl: { hostContains: 'bbc.co.uk' },
          }),
          new chrome.declarativeContent.PageStateMatcher({
            pageUrl: { hostContains: 'theguardian.com' },
          }),
          new chrome.declarativeContent.PageStateMatcher({
              pageUrl: { hostContains: 'dailymail.co.uk' },
          }),
        ],
      actions: [new chrome.declarativeContent.ShowPageAction()]
    }]);
  });
});

Vielen Dank, dass Sie sich die Zeit genommen haben, sich dieses Problem anzusehen/überprüfen, Lösungen im Zusammenhang mit der oben genannten „Vorhandene Erweiterungen deaktivieren“ sind nicht das, wonach ich suche.

  • Ihr Inhaltsskript ruft niemals auf sendResponse Ereignis, obwohl das Popup auf eine Antwort wartet.

    – Titus

    26. Januar 2020 um 0:11 Uhr

  • Hast du es geschafft, es mit sendResponse richtig zum Laufen zu bringen? als ich es versuchte, blieb der Fehler bestehen. Vielen Dank.

    – bongoSLAP

    26. Januar 2020 um 2:09 Uhr

Benutzer-Avatar
wOxxOm

Wenn Sie einen Rückruf für sendMessage angeben, teilen Sie dies der API mit Sie brauchen eine Antwort Wenn also Ihr Inhaltsskript nicht mit sendResponse antwortet, denkt die API, dass etwas Schreckliches passiert ist, und meldet es als solches!

Erinnerung: Stellen Sie beim Bearbeiten von Inhaltsskripten sicher, dass Sie beide Erweiterungen neu laden chrome://extensions Seite und die Registerkarten, die dieses Inhaltsskript haben sollen.

Sie brauchen keine Antwort:

  • Entfernen Sie den Rückruf in sendMessage

    chrome.tabs.sendMessage(tabs[0].id, {request: "Requesting headline"});
    
  • Entfernen return true – alles, was es derzeit tut, ist, der API zu sagen, dass sie den Messaging-Port auf unbestimmte Zeit offen halten soll, was niemals von Ihnen verwendet wird, also ist es nur eine Quelle für Speicherlecks.

    chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
      // do something
      // don't return true
      // ManifestV2: don't call sendResponse
      // ManifestV3 bug: uncomment the next line
      // sendResponse();
    });
    

    Für ManifestV3 in Chrome 99, 100, 101 benötigen Sie einen Dummy-Aufruf von sendResponse().

Sie brauchen eine Antwort:

  • Ersetzen return true mit sendResponse

    chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
      sendResponse('whatever');
    });
    

Sie benötigen eine Antwort von asynchron ausgeführtem Code wie zum Beispiel chrome API-Rückruf:

  • Halten return true

  • Forderung sendResponse(someImportantData) innerhalb des Rückrufs

    chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
      chrome.storage.local.set({foo: 'bar'}, () => {
        sendResponse('whatever');
      });
      return true;
    });
    

  • Ich verstehe. Ich habe es geschafft, es jetzt zum Laufen zu bringen, Sie haben es geschafft, den besten Einblick in dieses wiederkehrende Problem zu geben. Vielen Dank. 🙂

    – bongoSLAP

    26. Januar 2020 um 23:18 Uhr

  • Dies ist absolut die beste Antwort, die mir geholfen hat, dieses Problem zu lösen, das viel zu lange gedauert hat, um nützliche Informationen darüber zu finden. Meine leeren Callback-Funktionen wurden entfernt und meine Konsole ist wieder sauber.

    – r14n

    1. Oktober 2020 um 1:51 Uhr

  • Ich verwende Struts 1-Anwendung mit Iframes und js, jsp, html. Meine App funktioniert im IE, aber über Laufzeitproblemen in Chrome. Könnten Sie mir zeigen, wo genau ich dieses Stück platzieren muss. Die platzierte Haupt-js-Datei scheint diesen Inhalt nicht zu laden. jede Hilfe sehr geschätzt.

    – Satvidtech

    16. Dezember 2021 um 7:35 Uhr

1010120cookie-checkWie gehe ich mit “Unchecked runtime.lastError: The Message Port closed before a response was Received” um?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy