第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

將消息從后臺腳本發(fā)送到內(nèi)容腳本,然后發(fā)送到注入的腳本

將消息從后臺腳本發(fā)送到內(nèi)容腳本,然后發(fā)送到注入的腳本

慕森王 2019-11-25 20:16:05
將消息從后臺腳本發(fā)送到內(nèi)容腳本,然后發(fā)送到注入的腳本我正在嘗試將消息從后臺頁面發(fā)送到內(nèi)容腳本,然后將該內(nèi)容腳本中的消息發(fā)送到注入的腳本。我試過這個,但它沒有用。這是我的代碼的樣子。的manifest.json{   "manifest_version": 2,   "name": "NAME",   "description": ":D",   "version": "0.0",   "permissions": [     "tabs","<all_urls>"   ],   "content_scripts": [     {       "matches": ["<all_urls>"],       "js": ["content_script.js"]     }   ],   "web_accessible_resources": [       "injected.js"   ],   "background":{       "scripts":["background.js"]   }}background.jschrome.tabs.query({active: true, currentWindow: true}, function(tabs) {   chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello"}, function(response){});});content_script.jsvar s = document.createElement('script');s.src = chrome.extension.getURL('injected.js');s.onload = function(){          this.parentNode.removeChild(this);};(document.head||document.documentElement).appendChild(s);chrome.runtime.onMessage.addListener(   function(request, sender, sendResponse) {     document.dispatchEvent(new CustomEvent('Buffer2Remote', {todo: "LOL"}));});injected.jsdocument.addEventListener('Buffer2Remote', function(e){     alert(e.todo);});消息發(fā)送在第一部分background - > content_script中不起作用。我的代碼有什么問題嗎?
查看完整描述

2 回答

?
白豬掌柜的

TA貢獻1893條經(jīng)驗 獲得超10個贊

由于內(nèi)容腳本的注入方式,您的腳本不起作用。

問題

當(dāng)您(重新)加載擴展程序時,與某些人的預(yù)期相反,Chrome 不會將內(nèi)容腳本注入到與清單中的模式匹配的現(xiàn)有選項卡中。只有在加載擴展后,任何導(dǎo)航都會檢查URL以進行匹配,并將注入代碼。

那么,時間表:

  1. 你打開一些標(biāo)簽。沒有內(nèi)容腳本1。

  2. 您加載您的擴展程序。它的頂級代碼被執(zhí)行:它嘗試將消息傳遞給當(dāng)前選項卡。

  3. 由于那里還沒有聽眾,它失敗了。(這可能是chrome://extensions/頁面,你無論如何都不能注入)

  4. 之后,如果您嘗試導(dǎo)航/打開新選項卡,則會注入偵聽器,但不再執(zhí)行頂級代碼。

1 - 如果您重新加載擴展程序,也會發(fā)生這種情況。如果注入了內(nèi)容腳本,它將繼續(xù)處理其事件/不會被卸載,但無法再與擴展進行通信。(詳情見最后的附錄)

解決方案

解決方案1:您可以先向選項卡詢問您是否已準(zhǔn)備好發(fā)送消息,并在靜默時以編程方式注入腳本??紤]:

// Backgroundfunction ensureSendMessage(tabId, message, callback){
  chrome.tabs.sendMessage(tabId, {ping: true}, function(response){
    if(response && response.pong) { // Content script ready
      chrome.tabs.sendMessage(tabId, message, callback);
    } else { // No listener on the other end
      chrome.tabs.executeScript(tabId, {file: "content_script.js"}, function(){
        if(chrome.runtime.lastError) {
          console.error(chrome.runtime.lastError);
          throw Error("Unable to inject script into tab " + tabId);
        }
        // OK, now it's injected and ready
        chrome.tabs.sendMessage(tabId, message, callback);
      });
    }
  });}chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
  ensureSendMessage(tabs[0].id, {greeting: "hello"});});

// Content scriptchrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
  if(request.ping) { sendResponse({pong: true}); return; }
  /* Content script action */});

解決方案2:始終注入腳本,但要確保它只執(zhí)行一次。

// Backgroundfunction ensureSendMessage(tabId, message, callback){
  chrome.tabs.executeScript(tabId, {file: "content_script.js"}, function(){
    if(chrome.runtime.lastError) {
      console.error(chrome.runtime.lastError);
      throw Error("Unable to inject script into tab " + tabId);
    }
    // OK, now it's injected and ready
    chrome.tabs.sendMessage(tabId, message, callback);
  });}

// Content scriptvar injected;if(!injected){
  injected = true;
  /* your toplevel code */}

這更簡單,但在擴展重新加載方面存在復(fù)雜性。重新加載擴展后,舊腳本仍然存在1,但它不再是“你的”上下文 - 因此injected將是未定義的。注意可能兩次執(zhí)行腳本的副作用。


解決方案3:在初始化時不加選擇地注入內(nèi)容腳本。如果可以安全地運行相同的內(nèi)容腳本兩次,或者在頁面完全加載后運行它,則這樣做是安全的。

chrome.tabs.query({}, function(tabs) {
  for(var i in tabs) {
    // Filter by url if needed; that would require "tabs" permission
    // Note that injection will simply fail for tabs that you don't have permissions for
    chrome.tabs.executeScript(tabs[i].id, {file: "content_script.js"}, function() {
      // Now you can use normal messaging
    });
  }});

我還懷疑你希望它在一些動作上運行,而不是在擴展加載上運行。例如,您可以使用瀏覽器操作并將代碼包裝在chrome.browserAction.onClicked偵聽器中。


關(guān)于孤立內(nèi)容腳本的附錄

當(dāng)重新加載擴展程序時,人們會希望Chrome清理所有內(nèi)容腳本。但顯然事實并非如此; 內(nèi)容腳本的偵聽器未被禁用。但是,任何具有父擴展的消息都將失敗。這應(yīng)該被視為一個錯誤,并且可能在某些時候被修復(fù)。我要打電話給這個州“孤兒”

這在以下兩種情況中都不是問題:

  1. 內(nèi)容腳本沒有頁面上事件的偵聽器(例如,只執(zhí)行一次,或者只偵聽來自后臺的消息)

  2. 內(nèi)容腳本不對頁面執(zhí)行任何操作,僅發(fā)送有關(guān)事件的背景消息。

但是,如果情況并非如此,那么您就會遇到一個問題:內(nèi)容腳本可能正在執(zhí)行某些操作,但是會失敗或干擾另一個非孤立的實例。

解決方法是:

  1. 跟蹤頁面可以觸發(fā)的所有事件偵聽器

  2. 在對這些事件采取行動之前,請向背景發(fā)送“心跳”消息。3A。如果背景響應(yīng),我們很好,應(yīng)該執(zhí)行操作。3B。如果消息傳遞失敗,我們就是孤兒,應(yīng)該停止; 忽略該事件并取消注冊所有偵聽器。

代碼,內(nèi)容腳本:

function heartbeat(success, failure) {
  chrome.runtime.sendMessage({heartbeat: true}, function(reply){
    if(chrome.runtime.lastError){
      failure();
    } else {
      success();
    }
  });}function handler() {
  heartbeat(
    function(){ // hearbeat success
      /* Do stuff */
    }, 
    function(){ // hearbeat failure
      someEvent.removeListener(handler);
      console.log("Goodbye, cruel world!");
    }
  );}someEvent.addListener(handler);

背景腳本:

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
  if(request.heartbeat) { sendResponse(request); return; }
  /* ... */});



查看完整回答
反對 回復(fù) 2019-11-26
  • 2 回答
  • 0 關(guān)注
  • 413 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號