web-dev-qa-db-fra.com

Erreur de port: impossible d'établir la connexion. La fin de réception n'existe pas. En chrome

Je développe une extension dans Chrome et il y a un problème. Dans mon inject.js, Je fais une demande comme:

chrome.extension.sendRequest({command:'skip'},callback)

et dans mon `background.js j'ajoute simplement un Listener de requête comme:

chrome.extension.onrequest.addListener(function(req,sender,res){console.log("procession"})

Mais il y a une erreur:

Erreur de port: impossible d'établir la connexion. La fin de réception n'existe pas

Il semble qu'un bug dans le chrome? PS:
partie de mon manifeste.json

"background": {
    "scripts": ["background.js"]
  },
  "content_scripts": [
    {
      "matches": ["&lt all_urls &gt"], 
      "js": ["inject.js"]
    }
  ],

Je suis dans Chromium 17, et j'ai essayé de recharger l'extension, de rouvrir le navigateur ... rien ne s'est passé
quelqu'un a des idées?

51
Lanston

Je me suis retrouvé avec le même problème que vous décrivez ici. La solution que j'ai trouvée qui fonctionne pour moi est d'utiliser une page d'arrière-plan au lieu d'un script d'arrière-plan, comme ceci:

"background_page": "src/background.html",
  // maybe this seems to work instead of background { scripts [] }

  /* this gives a Port error: Could not ...
  "background": {
  "scripts": ["src/background.js"]
  },
  */

J'espère que cela fonctionne aussi pour vous.

9
Jasper

Ce n'est pas toujours la cause, mais si vous avez une erreur dans votre background.js, vous devriez vérifier ce lien:

Inspect views: _generated_background_page.html

dans la page Extensions, qui vous montrera toutes les erreurs JavaScript.

Cela empêchait mes connexions de s'établir.

21
Neil

Le problème pourrait être que sendRequest() et onRequest ont été dépréciés et remplacés par sendMessage() et onMessage. Depuis une récente mise à jour Chrome 20, ils semblent avoir complètement disparu.

La documentation officielle sur Message Passing ne mentionne même pas sendRequest() plus.

Voici un lien qui documente un peu le changement: http://codereview.chromium.org/9965005/

13
Jannes

Une page d'arrière-plan HTML ne fonctionnait pas pour moi dans Chrome 20.0.1132.57 m sous Windows 7 avec la même erreur:

Port error: Could not establish connection. Receiving end does not exist. miscellaneous_bindings:232

J'ai essayé d'utiliser un background.js script avec le contenu suivant:

chrome.extension.onConnect.addListener(function(port) {
    port.onMessage.addListener(function(msg) {
        // May be empty.
    });
});

Cela a résolu le onDisconnect immédiat dans mon script de contenu:

port = chrome.extension.connect();
port.onDisconnect.addListener(function (event) {
    // Happened immediately before adding the proper backend setup.
    // With proper backend setup, allows to determine the extension being disabled or unloaded.
});

Le code correct provient de l'exemple de messagerie de Chromium Extensions: http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/api/messaging/timer/page. js? view = markup

L'exemple contient également la deuxième partie qui sert de backend pour sendRequest, mais je ne l'ai pas testé moi-même:

chrome.extension.onRequest.addListener(
    function(request, sender, sendResponse) {
        // Don't know if it may be empty or a sendResponse call is required.
    });
5
sompylasar

Je voyais cette erreur en utilisant manifest_version: 2 et chrome.runtime.sendMessage. Je me connecte à partir d'une page Web à l'extension plutôt qu'à l'intérieur de l'extension.

La solution était de m'assurer que j'avais les bonnes valeurs dans le externally_connectable.matches array dans manifest.json. Vous devez répertorier les URL que vous souhaitez pouvoir vous connecter à l'extension. Voir https://developer.chrome.com/extensions/manifest/externally_connectable#without-externally-connectable .

2
Tayler

J'utilise sendMessage et onMessage pour la communication aussi, et dans mon workflow J'envoie d'abord un message depuis injected.js vers mon background.js et j'ai également reçu "Erreur de port: impossible d'établir la connexion. La fin de réception n'existe pas." Erreur.

J'ai donc décidé d'utiliser les fonctionnalités des réponses (comme ACK ), et si l'arrière-plan ne répond pas, je continue d'essayer avec un setTimeout comme ça.

//background.js

...
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
...
//some code

sendResponse({status: 'everything ok'})
return true;    
});

//injected.js

var myInjectedFunctionality = function() {

    chrome.extension.sendMessage({method: "Steroids:loadScripts"}, function(res) {
        if(res && res.status) {
            } else {
                setTimeout(myInjectedFunctionality, 3000);
            }
    });
};
myInjectedFunctionality();

Mon code fonctionne maintenant correctement, donc je pense que l'explication est facile à voir. Chrome ne prépare pas Background.js et les trucs de connexion quand il injecte votre code dans les pages où vous voulez, et ne fait donc écouter personne pour votre message envoyé, donc si personne n'écoute, continuez d'essayer comme moi.

1
robertovg

essayez d'injecter des scripts de contect dans un onglet dont l'url est chrome: // * ou https://chrome.google.com/*, lorsque vous connectez ces onglets en arrière-plan ,

par exemple

chrome.tabs.connect(tab.id).postMessage(msg)

puis jettera

Port error: Could not establish connection. Receiving end does not exist.

ces pages n'autorisent pas l'injection de scripts de contenu et la connexion se déconnectera immédiatement.

donc, vérifiez l'url et ne connectez pas ces onglets, puis l'exception n'est pas levée

1
愉阅-HappyReader

Face au même problème maintenant.

// Voici mon ancien background.js:

chrome.runtime.onInstalled.addListener(function () {
  //some other code here
  chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
    if (message.url) {
        chrome.downloads.download({
            url: message.url,
            conflictAction: 'uniquify',
            saveAs: false
        });
    }
});});//(Sorry, I tried but failed to put the last bracket on next line)

Vous voyez, le chrome.runtime.onMessage.addListener est déclenché lorsque l'événement onInstalled happpens, et quand je le sors de cette portée, et que mon code ressemble à ceci:

chrome.runtime.onInstalled.addListener(function () {
  //some other code here
});  
chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
    if (message.url) {
        chrome.downloads.download({
            url: message.url,
            conflictAction: 'uniquify',
            saveAs: false
        });
    }
});

Cela fonctionne bien maintenant. J'espère être utile.

1
Xiao Teng

Après un certain temps consacré à l'enquête, j'ai trouvé le problème dans mon cas.

Je reçois également:

Port error: Could not establish connection. Receiving end does not exist. 

Avant d'expliquer, je tiens à dire que j'utilise sendMessage et onMessage pour la communication.

Pour moi, cette erreur apparaît lorsque j'envoie un message de la page d'arrière-plan à un onglet où mon script de contenu s'exécute.

Mon extension ne fonctionne que sur les onglets où YouTube est ouvert. Donc, lorsque je modifie certaines préférences, je regarde pour voir quels onglets j'ai ouverts et envoyer un message pour mettre à jour les préférences mises à jour.

Dans un cas normal, cela fonctionne bien, mais si j'ai n (n> = 1) onglets avec youtube ouvert. Je clique sur le bouton "Recharger" pour l'extension, je change quelque chose ... les onglets youtube ne sont pas actualisés et ils ont perdu l'écouteur de message, donc je reçois cette erreur.

Il semble que c'est assez normal.

Si je rafraîchis les onglets YouTube après le rechargement de l'extension, je ne reçois pas cette erreur.

J'ai trouvé une solution, elle peut ne pas s'appliquer à tous les cas:

Quand j'ai eu ce problème, mon code était:

chrome.tabs.sendMessage(tabId, {proprName: proprName, newValue: newValue}, function(response) {});

Maintenant, mon code est:

chrome.tabs.sendMessage(tabId, {proprName: proprName, newValue: newValue});

Pour mon je n'avais pas besoin de rappel de réponse et parce que cela ne répondait pas, j'ai eu cette erreur.

1
darkyndy

Certaines des autres réponses ici ont de bons conseils de débogage ou de petites pièces du puzzle, cependant si vous voulez injecter dans des pages Web (tierces) comme moi , alors aucune réponse n'a répertorié les composants corrects.

Il y a 4 étapes:

  • un externe écouteur d'arrière-plan,
  • l'expéditeur du message de premier plan,
  • injecter l'ID d'extension pour l'expéditeur du message
  • et une règle dans le manifeste pour tout lier ensemble.

L'exemple ci-dessous devrait être tout ce dont vous avez besoin pour vous permettre d'injecter un js qui envoie des messages depuis n'importe quelle page de google.com vers votre propre extension

Tout d'abord dans le manifest.json vous devez ajouter les règles de messagerie qui sont décrites ici :

"externally_connectable": {
    "matches": ["*://*.google.com/*"]
}

Ensuite, dans votre script d'arrière-plan ou votre page, vous avez besoin d'un écouteur externe = (( Pas le chrome.runtime.onMessage.addListener régulier qui a été mentionné dans les réponses msot), c'est - décrit ici :

chrome.runtime.onMessageExternal.addListener( (request, sender, sendResponse) => {
    console.log("Received message from " + sender + ": ", request);
    sendResponse({ received: true }); //respond however you like
});

Une fois que vous disposez de ces pièces, vous pouvez utiliser un expéditeur de message comme vous le faites habituellement, mais avec l'ID d'extension comme premier paramètre:

chrome.runtime.sendMessage(myExtId, { /* whatever you want to send goes here */ },
    response => {
         /* handle the response from background here */
    }
);

Si vous ne savez pas comment obtenir l'identifiant externe que j'ai utilisé comme premier paramètre, vous pouvez injecter votre identifiant d'extension comme ci-dessous. Ceci est nécessaire car chrome.runtime.id et @@ extension_id ne fonctionnent pas dans les scripts injectés:

//create a script tag to inject, then set a variable with the id in that script
let idScript = document.createElement("script");
idScript.setAttribute("type", "application/javascript");
idScript.textContent = 'var myExtId = "' + chrome.runtime.id +'";';
let parent = ( document.head || document.documentElement );
parent.insertBefore( idScript, parent.firstChild );

//inject and run your other script here

idScript.remove(); //then cleanup 

Parce que nous le définissons comme var, l'autre script peut accéder directement à la valeur maintenant

0
Nick Cardoso

Consultez les derniers manuels: http://developer.chrome.com/extensions/messaging.html

Remarque: Si plusieurs pages écoutent des événements onMessage, seule la première à appeler sendResponse () pour un événement particulier réussira à envoyer la réponse. Toutes les autres réponses à cet événement seront ignorées.

Fermez vos onglets, ne laissez qu'une seule page et vérifiez. Dans mon cas, c'était le problème.

0
Andrey Uglev