7

我正在尋找一個網頁內的功能te激活一個Chrome擴展。從網站調用Chrome擴展的後臺功能

試想一下,http://www.example.com/test.html包含:

<script> 
hello(); 
</script> 

而且我的背景頁面包含hello函數的定義:

function hello() { 
    alert("test"); 
} 

我怎樣才能確保Chrome擴展的背景頁的hello被調用時test.html來電hello();

+0

不,你CA不是出於明顯的安全原因。該擴展需要公開其API的目的 – Bergi

回答

1

不,你上面的代碼,因爲background page(s) architecture

是與content scripts

示範使用內容腳本

的manifest.json

註冊內容腳本myscripts。 js

{ 
"name": "NFC", 
"description": "NFC Liken", 
"version": "0.1", 
"manifest_version": 2, 
"permissions": ["tabs", "http://*/", "https://*/"], 
"content_scripts": { 
    "matches": "http://www.example.com/*", 
    "js": [ "myscript.js"] 
    }, 
"browser_action": { 
"default_icon": "sync-icon.png", 
"default_title": "I Like I Tag" 
} 
} 

讓我知道你是否需要更多信息。

+0

謝謝你的答案。但是沒有交易..我也可以在myscript.js中使用這些函數。 函數clearhist(){ var millisecondsPerWeek = 1000 * 60 * 60 * 24 * 7; var oneWeekAgo =(new Date())。getTime() - millisecondsPerWeek; chrome.browsingData.remove({ 「因爲」:oneWeekAgo },{ 「應用程序緩存」:真實, 「緩存」:真實, 「曲奇」:真實, 「下載」:真實, 「文件系統」 :真, 「FORMDATA」:真實, 「歷史」:真實, 「IndexedDB的」:真實, 「的localStorage」:真實, 「pluginData」:真實, 「密碼」:真實, 「的WebSQL」:回調); true },callback); } –

+0

@WoutervanReeven:不能,你不能直接在myscript.js中放置這段代碼,但是你可以通過在'background'頁面中通過消息通信來間接調用代碼來實現。參考[這](http://stackoverflow.com/questions/13637715/not-receiving-any-data-from-webpage-to-content-js-of-chrome-extension/13638508#13638508)讓我知道,如果你需要更多的信息 – Sudarshan

+0

所以我需要在後臺js腳本中調用javascript函數。在頁面http://www.example.com/test.html的html中做些事情來調用Chrome擴展中的腳本。 背景HTML myscript.js 你好(); –

9

網頁是能夠調用後臺頁面的功能之前,需要以下亟待解決的問題:

  1. 能夠使用hello();從網頁。這是通過使用內容腳本定義hello的腳本injecting完成的。注入函數使用自定義事件或postMessage與內容腳本進行通信。
  2. 內容腳本需要與背景進行通信。這是通過chrome.runtime.sendMessage實現的。
    如果網頁需要得到回覆,以及:
  3. 發送從背景頁的答覆(sendMessage/onMessage,見下文)。
  4. 在內容腳本中,創建自定義事件或使用postMessage向網頁發送消息。
  5. 在網頁中處理此消息。

所有這些方法都是異步的,必須通過回調函數來實現。

這些步驟需要仔細設計。這是一個實現上述所有步驟的通用實現。您需要了解的實現:

  • 在要注入代碼中,每當需要聯繫內容腳本時,請使用sendMessage方法。
    用法:sendMessage(<mixed message> [, <function callback>])

contentscript.js

// Random unique name, to be used to minimize conflicts: 
var EVENT_FROM_PAGE = '__rw_chrome_ext_' + new Date().getTime(); 
var EVENT_REPLY = '__rw_chrome_ext_reply_' + new Date().getTime(); 

var s = document.createElement('script'); 
s.textContent = '(' + function(send_event_name, reply_event_name) { 
    // NOTE: This function is serialized and runs in the page's context 
    // Begin of the page's functionality 
    window.hello = function(string) { 
     sendMessage({ 
      type: 'sayhello', 
      data: string 
     }, function(response) { 
      alert('Background said: ' + response); 
     }); 
    }; 

    // End of your logic, begin of messaging implementation: 
    function sendMessage(message, callback) { 
     var transporter = document.createElement('dummy'); 
     // Handles reply: 
     transporter.addEventListener(reply_event_name, function(event) { 
      var result = this.getAttribute('result'); 
      if (this.parentNode) this.parentNode.removeChild(this); 
      // After having cleaned up, send callback if needed: 
      if (typeof callback == 'function') { 
       result = JSON.parse(result); 
       callback(result); 
      } 
     }); 
     // Functionality to notify content script 
     var event = document.createEvent('Events'); 
     event.initEvent(send_event_name, true, false); 
     transporter.setAttribute('data', JSON.stringify(message)); 
     (document.body||document.documentElement).appendChild(transporter); 
     transporter.dispatchEvent(event); 
    } 
} + ')(' + JSON.stringify(/*string*/EVENT_FROM_PAGE) + ', ' + 
      JSON.stringify(/*string*/EVENT_REPLY) + ');'; 
document.documentElement.appendChild(s); 
s.parentNode.removeChild(s); 


// Handle messages from/to page: 
document.addEventListener(EVENT_FROM_PAGE, function(e) { 
    var transporter = e.target; 
    if (transporter) { 
     var request = JSON.parse(transporter.getAttribute('data')); 
     // Example of handling: Send message to background and await reply 
     chrome.runtime.sendMessage({ 
      type: 'page', 
      request: request 
     }, function(data) { 
      // Received message from background, pass to page 
      var event = document.createEvent('Events'); 
      event.initEvent(EVENT_REPLY, false, false); 
      transporter.setAttribute('result', JSON.stringify(data)); 
      transporter.dispatchEvent(event); 
     }); 
    } 
}); 

background.js

chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) { 
    if (message && message.type == 'page') { 
     var page_message = message.message; 
     // Simple example: Get data from extension's local storage 
     var result = localStorage.getItem('whatever'); 
     // Reply result to content script 
     sendResponse(result); 
    } 
}); 

Chrome擴展程序,是不是不完整的清單文件,所以這裏的manifest.json文件,我用測試答案:

{ 
    "name": "Page to background and back again", 
    "version": "1", 
    "manifest_version": 2, 
    "background": { 
     "scripts": ["background.js"] 
    }, 
    "content_scripts": [{ 
     "matches": ["http://jsfiddle.net/jRaPj/show/*"], 
     "js": ["contentscript.js"], 
     "all_frames": true, 
     "run_at": "document_start" 
    }] 
} 

此擴展已在http://jsfiddle.net/jRaPj/show/(包含hello();,如問題中所示)進行測試,並顯示一個對話框,指出「Background說:null」。
打開後臺頁面,使用localStorage.setItem('whatever', 'Hello!');查看消息是否正確更改。

+0

@Xan'chrome.extension.sendMessage'是'chrome.runtime.sendMessage'的別名。你可能與'chrome.extension.sendRequest'混淆? –

+0

我並不困惑;但該功能已完全退役(文檔中未提及),但由於延續舊樣本代碼而不斷彈出新代碼。請參閱[此問題](https://code.google.com/p/chromium/issues/detail?id=495052)將其標記爲已棄用。 – Xan

0

有一個內置的解決方案Send messages from web pages到擴展

mainfest.json

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

網頁:

// The ID of the extension we want to talk to. 
var editorExtensionId = "abcdefghijklmnoabcdefhijklmnoabc"; 

// Make a simple request: 
chrome.runtime.sendMessage(editorExtensionId, {openUrlInEditor: url}, 
    function(response) { 
    if (!response.success) 
     handleError(url); 
    }); 

擴展的背景腳本:

chrome.runtime.onMessageExternal.addListener(
    function(request, sender, sendResponse) { 
    if (sender.url == blacklistedWebsite) 
     return; // don't allow this web page access 
    if (request.openUrlInEditor) 
     openUrl(request.openUrlInEditor); 
    }); 
相關問題